Added Get/SetThreadContext support through the server.

diff --git a/server/Makefile.in b/server/Makefile.in
index b4ec97a..e2bad9f 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -8,6 +8,7 @@
 C_SRCS = \
 	change.c \
 	console.c \
+	context_i386.c \
 	debugger.c \
 	device.c \
 	event.c \
diff --git a/server/context_i386.c b/server/context_i386.c
new file mode 100644
index 0000000..129577c
--- /dev/null
+++ b/server/context_i386.c
@@ -0,0 +1,264 @@
+/*
+ * i386 register context support
+ *
+ * Copyright (C) 1999 Alexandre Julliard
+ */
+
+#include "config.h"
+
+#ifdef __i386__
+
+#include <assert.h>
+#include <errno.h>
+#include <sys/ptrace.h>
+#include <sys/user.h>
+
+#include "winbase.h"
+#include "winerror.h"
+
+#include "thread.h"
+#include "request.h"
+
+
+#ifndef PTRACE_PEEKUSER
+#define PTRACE_PEEKUSER PT_READ_U
+#endif
+#ifndef PTRACE_POKEUSER
+#define PTRACE_POKEUSER PT_WRITE_U
+#endif
+#ifndef PTRACE_GETREGS
+#define PTRACE_GETREGS PT_GETREGS
+#endif
+#ifndef PTRACE_GETFPREGS
+#define PTRACE_GETFPREGS PT_GETFPREGS
+#endif
+
+#ifdef linux
+
+/* debug register offset in struct user */
+#define DR_OFFSET(dr) ((int)((((struct user *)0)->u_debugreg) + (dr)))
+
+/* retrieve a debug register */
+static inline int get_debug_reg( int pid, int num, DWORD *data )
+{
+    int res = ptrace( PTRACE_PEEKUSER, pid, DR_OFFSET(num), 0 );
+    if ((res == -1) && errno)
+    {
+        file_set_error();
+        return -1;
+    }
+    *data = res;
+    return 0;
+}
+
+/* retrieve a thread context */
+static void get_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context )
+{
+    int pid = thread->unix_pid;
+    if (flags & CONTEXT_FULL)
+    {
+        struct user_regs_struct regs;
+        if (ptrace( PTRACE_GETREGS, pid, 0, &regs ) == -1) goto error;
+        if (flags & CONTEXT_INTEGER)
+        {
+            context->Eax = regs.eax;
+            context->Ebx = regs.ebx;
+            context->Ecx = regs.ecx;
+            context->Edx = regs.edx;
+            context->Esi = regs.esi;
+            context->Edi = regs.edi;
+        }
+        if (flags & CONTEXT_CONTROL)
+        {
+            context->Ebp    = regs.ebp;
+            context->Esp    = regs.esp;
+            context->Eip    = regs.eip;
+            context->SegCs  = regs.xcs & 0xffff;
+            context->SegSs  = regs.xss & 0xffff;
+            context->EFlags = regs.eflags;
+        }
+        if (flags & CONTEXT_SEGMENTS)
+        {
+            context->SegDs = regs.xds & 0xffff;
+            context->SegEs = regs.xes & 0xffff;
+            context->SegFs = regs.xfs & 0xffff;
+            context->SegGs = regs.xgs & 0xffff;
+        }
+    }
+    if (flags & CONTEXT_DEBUG_REGISTERS)
+    {
+        if (get_debug_reg( pid, 0, &context->Dr0 ) == -1) goto error;
+        if (get_debug_reg( pid, 1, &context->Dr1 ) == -1) goto error;
+        if (get_debug_reg( pid, 2, &context->Dr2 ) == -1) goto error;
+        if (get_debug_reg( pid, 3, &context->Dr3 ) == -1) goto error;
+        if (get_debug_reg( pid, 6, &context->Dr6 ) == -1) goto error;
+        if (get_debug_reg( pid, 7, &context->Dr7 ) == -1) goto error;
+    }
+    if (flags & CONTEXT_FLOATING_POINT)
+    {
+        /* we can use context->FloatSave directly as it is using the */
+        /* correct structure (the same as fsave/frstor) */
+        if (ptrace( PTRACE_GETFPREGS, pid, 0, &context->FloatSave ) == -1) goto error;
+        context->FloatSave.Cr0NpxState = 0;  /* FIXME */
+    }
+    return;
+ error:
+    file_set_error();
+}
+
+
+/* set a thread context */
+static void set_thread_context( struct thread *thread, unsigned int flags, CONTEXT *context )
+{
+    int pid = thread->unix_pid;
+    if (flags & CONTEXT_FULL)
+    {
+        struct user_regs_struct regs;
+        if ((flags & CONTEXT_FULL) != CONTEXT_FULL)  /* need to preserve some registers */
+        {
+            if (ptrace( PTRACE_GETREGS, pid, 0, &regs ) == -1) goto error;
+        }
+        if (flags & CONTEXT_INTEGER)
+        {
+            regs.eax = context->Eax;
+            regs.ebx = context->Ebx;
+            regs.ecx = context->Ecx;
+            regs.edx = context->Edx;
+            regs.esi = context->Esi;
+            regs.edi = context->Edi;
+        }
+        if (flags & CONTEXT_CONTROL)
+        {
+            regs.ebp = context->Ebp;
+            regs.esp = context->Esp;
+            regs.eip = context->Eip;
+            regs.xcs = context->SegCs;
+            regs.xss = context->SegSs;
+            regs.eflags = context->EFlags;
+        }
+        if (flags & CONTEXT_SEGMENTS)
+        {
+            regs.xds = context->SegDs;
+            regs.xes = context->SegEs;
+            regs.xfs = context->SegFs;
+            regs.xgs = context->SegGs;
+        }
+        if (ptrace( PTRACE_SETREGS, pid, 0, &regs ) == -1) goto error;
+    }
+    if (flags & CONTEXT_DEBUG_REGISTERS)
+    {
+        if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(0), context->Dr0 ) == -1) goto error;
+        if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(1), context->Dr1 ) == -1) goto error;
+        if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(2), context->Dr2 ) == -1) goto error;
+        if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(3), context->Dr3 ) == -1) goto error;
+        if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(6), context->Dr6 ) == -1) goto error;
+        if (ptrace( PTRACE_POKEUSER, pid, DR_OFFSET(7), context->Dr7 ) == -1) goto error;
+    }
+    if (flags & CONTEXT_FLOATING_POINT)
+    {
+        /* we can use context->FloatSave directly as it is using the */
+        /* correct structure (the same as fsave/frstor) */
+        if (ptrace( PTRACE_SETFPREGS, pid, 0, &context->FloatSave ) == -1) goto error;
+        context->FloatSave.Cr0NpxState = 0;  /* FIXME */
+    }
+    return;
+ error:
+    file_set_error();
+}
+
+#else  /* linux */
+#error You must implement get/set_thread_context for your platform
+#endif  /* linux */
+
+
+/* copy a context structure according to the flags */
+static void copy_context( CONTEXT *to, CONTEXT *from, int flags )
+{
+    if (flags & CONTEXT_CONTROL)
+    {
+        to->Ebp    = from->Ebp;
+        to->Eip    = from->Eip;
+        to->Esp    = from->Esp;
+        to->SegCs  = from->SegCs;
+        to->SegSs  = from->SegSs;
+        to->EFlags = from->EFlags;
+    }
+    if (flags & CONTEXT_INTEGER)
+    {
+        to->Eax = from->Eax;
+        to->Ebx = from->Ebx;
+        to->Ecx = from->Ecx;
+        to->Edx = from->Edx;
+        to->Esi = from->Esi;
+        to->Edi = from->Edi;
+    }
+    if (flags & CONTEXT_SEGMENTS)
+    {
+        to->SegDs = from->SegDs;
+        to->SegEs = from->SegEs;
+        to->SegFs = from->SegFs;
+        to->SegGs = from->SegGs;
+    }
+    if (flags & CONTEXT_DEBUG_REGISTERS)
+    {
+        to->Dr0 = from->Dr0;
+        to->Dr1 = from->Dr1;
+        to->Dr2 = from->Dr2;
+        to->Dr3 = from->Dr3;
+        to->Dr6 = from->Dr6;
+        to->Dr7 = from->Dr7;
+    }
+    if (flags & CONTEXT_FLOATING_POINT)
+    {
+        to->FloatSave = from->FloatSave;
+    }
+}
+
+/* retrieve the current context of a thread */
+DECL_HANDLER(get_thread_context)
+{
+    struct thread *thread;
+    CONTEXT *context;
+
+    if ((thread = get_thread_from_handle( req->handle, THREAD_GET_CONTEXT )))
+    {
+        if ((context = get_debug_context( thread )))  /* thread is inside an exception event */
+        {
+            copy_context( &req->context, context, req->flags );
+        }
+        else
+        {
+            suspend_thread( thread, 0 );
+            if (thread->attached) get_thread_context( thread, req->flags, &req->context );
+            else set_error( ERROR_ACCESS_DENIED );
+            resume_thread( thread );
+        }
+        release_object( thread );
+    }
+}
+
+
+/* set the current context of a thread */
+DECL_HANDLER(set_thread_context)
+{
+    struct thread *thread;
+    CONTEXT *context;
+
+    if ((thread = get_thread_from_handle( req->handle, THREAD_SET_CONTEXT )))
+    {
+        if ((context = get_debug_context( thread )))  /* thread is inside an exception event */
+        {
+            copy_context( context, &req->context, req->flags );
+        }
+        else
+        {
+            suspend_thread( thread, 0 );
+            if (thread->attached) set_thread_context( thread, req->flags, &req->context );
+            else set_error( ERROR_ACCESS_DENIED );
+            resume_thread( thread );
+        }
+        release_object( thread );
+    }
+}
+
+#endif  /* __i386__ */
diff --git a/server/debugger.c b/server/debugger.c
index 6e370e0..7cbf183 100644
--- a/server/debugger.c
+++ b/server/debugger.c
@@ -28,8 +28,7 @@
     struct thread         *debugger;  /* debugger thread receiving the event */
     enum debug_event_state state;     /* event state */
     int                    status;    /* continuation status */
-    int                    code;      /* event code */
-    union debug_event_data data;      /* event data */
+    debug_event_t          data;      /* event data */
 };
 
 /* debug context */
@@ -84,21 +83,6 @@
     debug_ctx_destroy              /* destroy */
 };
 
-/* size of the event data */
-static const int event_sizes[] =
-{
-    0,
-    sizeof(struct debug_event_exception),       /* EXCEPTION_DEBUG_EVENT */
-    sizeof(struct debug_event_create_thread),   /* CREATE_THREAD_DEBUG_EVENT */
-    sizeof(struct debug_event_create_process),  /* CREATE_PROCESS_DEBUG_EVENT */
-    sizeof(struct debug_event_exit),            /* EXIT_THREAD_DEBUG_EVENT */
-    sizeof(struct debug_event_exit),            /* EXIT_PROCESS_DEBUG_EVENT */
-    sizeof(struct debug_event_load_dll),        /* LOAD_DLL_DEBUG_EVENT */
-    sizeof(struct debug_event_unload_dll),      /* UNLOAD_DLL_DEBUG_EVENT */
-    sizeof(struct debug_event_output_string),   /* OUTPUT_DEBUG_STRING_EVENT */
-    sizeof(struct debug_event_rip_info)         /* RIP_EVENT */
-};
-
 
 /* initialise the fields that do not need to be filled by the client */
 static int fill_debug_event( struct thread *debugger, struct thread *thread,
@@ -107,45 +91,45 @@
     int handle;
 
     /* some events need special handling */
-    switch(event->code)
+    switch(event->data.code)
     {
     case CREATE_THREAD_DEBUG_EVENT:
-        if ((event->data.create_thread.handle = alloc_handle( debugger->process, thread,
+        if ((event->data.info.create_thread.handle = alloc_handle( debugger->process, thread,
                /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
                                                               THREAD_ALL_ACCESS, FALSE )) == -1)
             return 0;
         break;
     case CREATE_PROCESS_DEBUG_EVENT:
-        if ((handle = event->data.create_process.file) != -1)
+        if ((handle = event->data.info.create_process.file) != -1)
         {
             if ((handle = duplicate_handle( thread->process, handle, debugger->process,
                                             GENERIC_READ, FALSE, 0 )) == -1)
                 return 0;
-            event->data.create_process.file = handle;
+            event->data.info.create_process.file = handle;
         }
-        if ((event->data.create_process.process = alloc_handle( debugger->process, thread->process,
+        if ((event->data.info.create_process.process = alloc_handle( debugger->process, thread->process,
                                            /* documented: PROCESS_VM_READ | PROCESS_VM_WRITE */
                                                                 PROCESS_ALL_ACCESS, FALSE )) == -1)
         {
             if (handle != -1) close_handle( debugger->process, handle );
             return 0;
         }
-        if ((event->data.create_process.thread = alloc_handle( debugger->process, thread,
+        if ((event->data.info.create_process.thread = alloc_handle( debugger->process, thread,
                /* documented: THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME */
                                                                THREAD_ALL_ACCESS, FALSE )) == -1)
         {
             if (handle != -1) close_handle( debugger->process, handle );
-            close_handle( debugger->process, event->data.create_process.process );
+            close_handle( debugger->process, event->data.info.create_process.process );
             return 0;
         }
         break;
     case LOAD_DLL_DEBUG_EVENT:
-        if ((handle = event->data.load_dll.handle) != -1)
+        if ((handle = event->data.info.load_dll.handle) != -1)
         {
             if ((handle = duplicate_handle( thread->process, handle, debugger->process,
                                             GENERIC_READ, FALSE, 0 )) == -1)
                 return 0;
-            event->data.load_dll.handle = handle;
+            event->data.info.load_dll.handle = handle;
         }
         break;
     }
@@ -196,14 +180,14 @@
 
         event->state = EVENT_SENT;
         debug_ctx->to_send = event->next;
-        req->code = event->code;
+        req->event.code = event->data.code;
         req->pid  = event->sender->process;
         req->tid  = event->sender;
-        memcpy( req + 1, &event->data, event_sizes[event->code] );
+        memcpy( &req->event, &event->data, sizeof(req->event) );
     }
     else  /* timeout or error */
     {
-        req->code = 0;
+        req->event.code = 0;
         req->pid  = 0;
         req->tid  = 0;
         thread->error = signaled;
@@ -219,8 +203,10 @@
 
     req->status = event->status;
     /* copy the context into the reply */
-    if (event->code == EXCEPTION_DEBUG_EVENT)
-        memcpy( req + 1, &event->data, event_sizes[event->code] );
+    if (event->data.code == EXCEPTION_DEBUG_EVENT)
+        memcpy( &req->event.info.exception.context,
+                &event->data.info.exception.context,
+                sizeof(req->event.info.exception.context) );
 }
 
 static void debug_event_dump( struct object *obj, int verbose )
@@ -228,7 +214,7 @@
     struct debug_event *debug_event = (struct debug_event *)obj;
     assert( obj->ops == &debug_event_ops );
     fprintf( stderr, "Debug event sender=%p code=%d state=%d\n",
-             debug_event->sender, debug_event->code, debug_event->state );
+             debug_event->sender, debug_event->data.code, debug_event->state );
 }
 
 static int debug_event_signaled( struct object *obj, struct thread *thread )
@@ -252,20 +238,20 @@
     if (event->state == EVENT_QUEUED)
     {
         struct process *debugger = event->debugger->process;
-        switch(event->code)
+        switch(event->data.code)
         {
         case CREATE_THREAD_DEBUG_EVENT:
-            close_handle( debugger, event->data.create_thread.handle );
+            close_handle( debugger, event->data.info.create_thread.handle );
             break;
         case CREATE_PROCESS_DEBUG_EVENT:
-            if (event->data.create_process.file != -1)
-                close_handle( debugger, event->data.create_process.file );
-            close_handle( debugger, event->data.create_process.thread );
-            close_handle( debugger, event->data.create_process.process );
+            if (event->data.info.create_process.file != -1)
+                close_handle( debugger, event->data.info.create_process.file );
+            close_handle( debugger, event->data.info.create_process.thread );
+            close_handle( debugger, event->data.info.create_process.process );
             break;
         case LOAD_DLL_DEBUG_EVENT:
-            if (event->data.load_dll.handle != -1)
-                close_handle( debugger, event->data.load_dll.handle );
+            if (event->data.info.load_dll.handle != -1)
+                close_handle( debugger, event->data.info.load_dll.handle );
             break;
         }
     }
@@ -346,7 +332,7 @@
 
 /* queue a debug event for a debugger */
 static struct debug_event *queue_debug_event( struct thread *debugger, struct thread *thread,
-                                              int code, void *data )
+                                              debug_event_t *data )
 {
     struct debug_ctx *debug_ctx = debugger->debug_ctx;
     struct debug_event *event;
@@ -360,14 +346,13 @@
     event->next     = NULL;
     event->prev     = NULL;
     event->state    = EVENT_QUEUED;
-    event->code     = code;
     event->sender   = (struct thread *)grab_object( thread );
     event->debugger = (struct thread *)grab_object( debugger );
-    memcpy( &event->data, data, event_sizes[code] );
+    memcpy( &event->data, data, sizeof(event->data) );
 
     if (!fill_debug_event( debugger, thread, event ))
     {
-        event->code = -1;  /* make sure we don't attempt to close handles */
+        event->data.code = -1;  /* make sure we don't attempt to close handles */
         release_object( event );
         return NULL;
     }
@@ -377,6 +362,22 @@
     return event;
 }
 
+/* return a pointer to the context in case the thread is inside an exception event */
+CONTEXT *get_debug_context( struct thread *thread )
+{
+    struct debug_event *event;
+    struct thread *debugger = thread->process->debugger;
+
+    if (!debugger) return NULL;  /* not being debugged */
+    assert( debugger->debug_ctx );
+
+    /* find the exception event in the debugger's queue */
+    for (event = debugger->debug_ctx->event_head; event; event = event->next)
+        if (event->sender == thread && (event->data.code == EXCEPTION_DEBUG_EVENT))
+            return &event->data.info.exception.context;
+    return NULL;
+}
+
 /* attach a process to a debugger thread */
 int debugger_attach( struct process *process, struct thread *debugger )
 {
@@ -417,13 +418,12 @@
     if (debugger)  /* being debugged -> send an event to the debugger */
     {
         struct debug_event *event;
-        struct debug_event_exit exit;
-        exit.exit_code = exit_code;
-        if (thread->process->running_threads == 1)
-            /* this is the last thread, send an exit process event */
-            event = queue_debug_event( debugger, thread, EXIT_PROCESS_DEBUG_EVENT, &exit );
-        else
-            event = queue_debug_event( debugger, thread, EXIT_THREAD_DEBUG_EVENT, &exit );
+        debug_event_t exit;
+        exit.info.exit.exit_code = exit_code;
+        /* if this is the last thread, send an exit process event */
+        exit.code = ((thread->process->running_threads == 1) ?
+                     EXIT_PROCESS_DEBUG_EVENT : EXIT_THREAD_DEBUG_EVENT);
+        event = queue_debug_event( debugger, thread, &exit );
         if (event) release_object( event );
     }
 
@@ -441,9 +441,9 @@
 {
     if (!wait_for_debug_event( req->timeout ))
     {
-        req->code = 0;
-        req->pid  = NULL;
-        req->tid  = NULL;
+        req->event.code = 0;
+        req->pid = NULL;
+        req->tid = NULL;
     }
 }
 
@@ -481,13 +481,13 @@
     struct thread *debugger = current->process->debugger;
     struct debug_event *event;
 
-    if ((req->code <= 0) || (req->code > RIP_EVENT))
+    if ((req->event.code <= 0) || (req->event.code > RIP_EVENT))
     {
-        fatal_protocol_error( current, "send_debug_event: bad code %d\n", req->code );
+        fatal_protocol_error( current, "send_debug_event: bad code %d\n", req->event.code );
         return;
     }
     req->status = 0;
-    if (debugger && ((event = queue_debug_event( debugger, current, req->code, req + 1 ))))
+    if (debugger && ((event = queue_debug_event( debugger, current, &req->event ))))
     {
         /* wait for continue_debug_event */
         struct object *obj = &event->obj;
diff --git a/server/object.h b/server/object.h
index 5825dce..fb874f7 100644
--- a/server/object.h
+++ b/server/object.h
@@ -155,6 +155,7 @@
 
 extern int debugger_attach( struct process *process, struct thread *debugger );
 extern void debug_exit_thread( struct thread *thread, int exit_code );
+extern CONTEXT *get_debug_context( struct thread *thread );
 
 /* mapping functions */
 
diff --git a/server/request.h b/server/request.h
index da50d44..80ad9aa 100644
--- a/server/request.h
+++ b/server/request.h
@@ -157,6 +157,8 @@
 DECL_HANDLER(open_timer);
 DECL_HANDLER(set_timer);
 DECL_HANDLER(cancel_timer);
+DECL_HANDLER(get_thread_context);
+DECL_HANDLER(set_thread_context);
 
 #ifdef WANT_REQUEST_HANDLERS
 
@@ -254,6 +256,8 @@
     { (void(*)())req_open_timer, sizeof(struct open_timer_request) },
     { (void(*)())req_set_timer, sizeof(struct set_timer_request) },
     { (void(*)())req_cancel_timer, sizeof(struct cancel_timer_request) },
+    { (void(*)())req_get_thread_context, sizeof(struct get_thread_context_request) },
+    { (void(*)())req_set_thread_context, sizeof(struct set_thread_context_request) },
 };
 #endif  /* WANT_REQUEST_HANDLERS */
 
diff --git a/server/trace.c b/server/trace.c
index 35fb9e7..7fc5eb6 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -9,6 +9,7 @@
 #include <sys/types.h>
 #include <sys/uio.h>
 #include "winsock2.h"
+#include "winnt.h"
 #include "request.h"
 #include "unicode.h"
 
@@ -26,6 +27,17 @@
     fputc( '}', stderr );
 }
 
+static void dump_uints( const int *ptr, int len )
+{
+    fputc( '{', stderr );
+    while (len)
+    {
+        fprintf( stderr, "%08x", *ptr++ );
+        if (--len) fputc( ',', stderr );
+    }
+    fputc( '}', stderr );
+}
+
 static void dump_bytes( const unsigned char *ptr, int len )
 {
     fputc( '{', stderr );
@@ -44,15 +56,103 @@
     fputc( '\"', stderr );
 }
 
+static void dump_path_t( const path_t *path )
+{
+    dump_unicode_string( *path );
+}
+
+static void dump_context( const CONTEXT *context )
+{
+#ifdef __i386__
+    fprintf( stderr, "{flags=%08lx,eax=%08lx,ebx=%08lx,ecx=%08lx,edx=%08lx,esi=%08lx,edi=%08lx,"
+             "ebp=%08lx,eip=%08lx,esp=%08lx,eflags=%08lx,cs=%04lx,ds=%04lx,es=%04lx,"
+             "fs=%04lx,gs=%04lx,dr0=%08lx,dr1=%08lx,dr2=%08lx,dr3=%08lx,dr6=%08lx,dr7=%08lx,",
+             context->ContextFlags, context->Eax, context->Ebx, context->Ecx, context->Edx,
+             context->Esi, context->Edi, context->Ebp, context->Eip, context->Esp, context->EFlags,
+             context->SegCs, context->SegDs, context->SegEs, context->SegFs, context->SegGs,
+             context->Dr0, context->Dr1, context->Dr2, context->Dr3, context->Dr6, context->Dr7 );
+    fprintf( stderr, "float=" );
+    dump_uints( (int *)&context->FloatSave, sizeof(context->FloatSave) / sizeof(int) );
+    fprintf( stderr, "}" );
+#else
+    dump_uints( (int *)context, sizeof(*context) / sizeof(int) );
+#endif
+}
+
+static void dump_debug_event_t( const debug_event_t *event )
+{
+    int i;
+    switch(event->code)
+    {
+    case EXCEPTION_DEBUG_EVENT:
+        fprintf( stderr, "{exception,code=%x,flags=%x,rec=%p,addr=%p,params={",
+                 event->info.exception.code, event->info.exception.flags,
+                 event->info.exception.record, event->info.exception.addr );
+        for (i = 0; i < event->info.exception.nb_params; i++)
+        {
+            if (i) fputc( ',', stderr );
+            fprintf( stderr, "%x", event->info.exception.params[i] );
+        }
+        fprintf( stderr, "},first_chance=%d,context=", event->info.exception.first_chance );
+        dump_context( &event->info.exception.context );
+        fputc( '}', stderr );
+        break;
+    case CREATE_THREAD_DEBUG_EVENT:
+        fprintf( stderr, "{create_thread,thread=%d,teb=%p,start=%p}",
+                 event->info.create_thread.handle, event->info.create_thread.teb,
+                 event->info.create_thread.start );
+        break;
+    case CREATE_PROCESS_DEBUG_EVENT:
+        fprintf( stderr, "{create_process,file=%d,process=%d,thread=%d,base=%p,offset=%d,"
+                         "size=%d,teb=%p,start=%p,name=%p,unicode=%d}",
+                 event->info.create_process.file, event->info.create_process.process,
+                 event->info.create_process.thread, event->info.create_process.base,
+                 event->info.create_process.dbg_offset, event->info.create_process.dbg_size,
+                 event->info.create_process.teb, event->info.create_process.start,
+                 event->info.create_process.name, event->info.create_process.unicode );
+        break;
+    case EXIT_THREAD_DEBUG_EVENT:
+        fprintf( stderr, "{exit_thread,code=%d}", event->info.exit.exit_code );
+        break;
+    case EXIT_PROCESS_DEBUG_EVENT:
+        fprintf( stderr, "{exit_process,code=%d}", event->info.exit.exit_code );
+        break;
+    case LOAD_DLL_DEBUG_EVENT:
+        fprintf( stderr, "{load_dll,file=%d,base=%p,offset=%d,size=%d,name=%p,unicode=%d}",
+                 event->info.load_dll.handle, event->info.load_dll.base,
+                 event->info.load_dll.dbg_offset, event->info.load_dll.dbg_size,
+                 event->info.load_dll.name, event->info.load_dll.unicode );
+        break;
+    case UNLOAD_DLL_DEBUG_EVENT:
+        fprintf( stderr, "{unload_dll,base=%p}", event->info.unload_dll.base );
+        break;
+    case OUTPUT_DEBUG_STRING_EVENT:
+        fprintf( stderr, "{output_string,data=%p,unicode=%d,len=%d}",
+                 event->info.output_string.string, event->info.output_string.unicode,
+                 event->info.output_string.length );
+        break;
+    case RIP_EVENT:
+        fprintf( stderr, "{rip,err=%d,type=%d}",
+                 event->info.rip_info.error, event->info.rip_info.type );
+        break;
+    case 0:  /* zero is the code returned on timeouts */
+        fprintf( stderr, "{}" );
+        break;
+    default:
+        fprintf( stderr, "{code=??? (%d)}", event->code );
+        break;
+    }
+}
+
 
 /* dumping for functions for requests that have a variable part */
 
-static void dump_varargs_select_request( struct select_request *req )
+static void dump_varargs_select_request( const struct select_request *req )
 {
     dump_ints( req->handles, req->count );
 }
 
-static void dump_varargs_get_apcs_reply( struct get_apcs_request *req )
+static void dump_varargs_get_apcs_reply( const struct get_apcs_request *req )
 {
     int i;
     for (i = 0; i < 2 * req->count; i++)
@@ -60,34 +160,34 @@
     fprintf( stderr, "}" );
 }
 
-static void dump_varargs_get_socket_event_reply( struct get_socket_event_request *req )
+static void dump_varargs_get_socket_event_reply( const struct get_socket_event_request *req )
 {
     dump_ints( req->errors, FD_MAX_EVENTS );
 }
 
-static void dump_varargs_read_process_memory_reply( struct read_process_memory_request *req )
+static void dump_varargs_read_process_memory_reply( const struct read_process_memory_request *req )
 {
     int count = MIN( req->len, get_req_size( req->data, sizeof(int) ) );
     dump_bytes( (unsigned char *)req->data, count * sizeof(int) );
 }
 
-static void dump_varargs_write_process_memory_request( struct write_process_memory_request *req )
+static void dump_varargs_write_process_memory_request( const struct write_process_memory_request *req )
 {
     int count = MIN( req->len, get_req_size( req->data, sizeof(int) ) );
     dump_bytes( (unsigned char *)req->data, count * sizeof(int) );
 }
 
-static void dump_varargs_set_key_value_request( struct set_key_value_request *req )
+static void dump_varargs_set_key_value_request( const struct set_key_value_request *req )
 {
     dump_bytes( req->data, req->len );
 }
 
-static void dump_varargs_get_key_value_reply( struct get_key_value_request *req )
+static void dump_varargs_get_key_value_reply( const struct get_key_value_request *req )
 {
     dump_bytes( req->data, req->len );
 }
 
-static void dump_varargs_enum_key_value_reply( struct enum_key_value_request *req )
+static void dump_varargs_enum_key_value_reply( const struct enum_key_value_request *req )
 {
     dump_bytes( req->data, req->len );
 }
@@ -97,7 +197,7 @@
 /* Everything below this line is generated automatically by tools/make_requests */
 /* ### make_requests begin ### */
 
-static void dump_new_process_request( struct new_process_request *req )
+static void dump_new_process_request( const struct new_process_request *req )
 {
     fprintf( stderr, " inherit=%d,", req->inherit );
     fprintf( stderr, " inherit_all=%d,", req->inherit_all );
@@ -112,35 +212,35 @@
     fprintf( stderr, " cmdline=\"%s\"", req->cmdline );
 }
 
-static void dump_new_process_reply( struct new_process_request *req )
+static void dump_new_process_reply( const struct new_process_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_new_thread_request( struct new_thread_request *req )
+static void dump_new_thread_request( const struct new_thread_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " suspend=%d,", req->suspend );
     fprintf( stderr, " inherit=%d", req->inherit );
 }
 
-static void dump_new_thread_reply( struct new_thread_request *req )
+static void dump_new_thread_reply( const struct new_thread_request *req )
 {
     fprintf( stderr, " tid=%p,", req->tid );
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_set_debug_request( struct set_debug_request *req )
+static void dump_set_debug_request( const struct set_debug_request *req )
 {
     fprintf( stderr, " level=%d", req->level );
 }
 
-static void dump_init_process_request( struct init_process_request *req )
+static void dump_init_process_request( const struct init_process_request *req )
 {
 }
 
-static void dump_init_process_reply( struct init_process_request *req )
+static void dump_init_process_reply( const struct init_process_request *req )
 {
     fprintf( stderr, " start_flags=%d,", req->start_flags );
     fprintf( stderr, " hstdin=%d,", req->hstdin );
@@ -151,46 +251,46 @@
     fprintf( stderr, " cmdline=\"%s\"", req->cmdline );
 }
 
-static void dump_init_process_done_request( struct init_process_done_request *req )
+static void dump_init_process_done_request( const struct init_process_done_request *req )
 {
     fprintf( stderr, " dummy=%d", req->dummy );
 }
 
-static void dump_init_thread_request( struct init_thread_request *req )
+static void dump_init_thread_request( const struct init_thread_request *req )
 {
     fprintf( stderr, " unix_pid=%d,", req->unix_pid );
     fprintf( stderr, " teb=%p", req->teb );
 }
 
-static void dump_init_thread_reply( struct init_thread_request *req )
+static void dump_init_thread_reply( const struct init_thread_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " tid=%p", req->tid );
 }
 
-static void dump_get_thread_buffer_request( struct get_thread_buffer_request *req )
+static void dump_get_thread_buffer_request( const struct get_thread_buffer_request *req )
 {
     fprintf( stderr, " dummy=%d", req->dummy );
 }
 
-static void dump_terminate_process_request( struct terminate_process_request *req )
+static void dump_terminate_process_request( const struct terminate_process_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " exit_code=%d", req->exit_code );
 }
 
-static void dump_terminate_thread_request( struct terminate_thread_request *req )
+static void dump_terminate_thread_request( const struct terminate_thread_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " exit_code=%d", req->exit_code );
 }
 
-static void dump_get_process_info_request( struct get_process_info_request *req )
+static void dump_get_process_info_request( const struct get_process_info_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_get_process_info_reply( struct get_process_info_request *req )
+static void dump_get_process_info_reply( const struct get_process_info_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " exit_code=%d,", req->exit_code );
@@ -199,7 +299,7 @@
     fprintf( stderr, " system_affinity=%d", req->system_affinity );
 }
 
-static void dump_set_process_info_request( struct set_process_info_request *req )
+static void dump_set_process_info_request( const struct set_process_info_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " mask=%d,", req->mask );
@@ -207,19 +307,19 @@
     fprintf( stderr, " affinity=%d", req->affinity );
 }
 
-static void dump_get_thread_info_request( struct get_thread_info_request *req )
+static void dump_get_thread_info_request( const struct get_thread_info_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_get_thread_info_reply( struct get_thread_info_request *req )
+static void dump_get_thread_info_reply( const struct get_thread_info_request *req )
 {
     fprintf( stderr, " tid=%p,", req->tid );
     fprintf( stderr, " exit_code=%d,", req->exit_code );
     fprintf( stderr, " priority=%d", req->priority );
 }
 
-static void dump_set_thread_info_request( struct set_thread_info_request *req )
+static void dump_set_thread_info_request( const struct set_thread_info_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " mask=%d,", req->mask );
@@ -227,72 +327,72 @@
     fprintf( stderr, " affinity=%d", req->affinity );
 }
 
-static void dump_suspend_thread_request( struct suspend_thread_request *req )
+static void dump_suspend_thread_request( const struct suspend_thread_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_suspend_thread_reply( struct suspend_thread_request *req )
+static void dump_suspend_thread_reply( const struct suspend_thread_request *req )
 {
     fprintf( stderr, " count=%d", req->count );
 }
 
-static void dump_resume_thread_request( struct resume_thread_request *req )
+static void dump_resume_thread_request( const struct resume_thread_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_resume_thread_reply( struct resume_thread_request *req )
+static void dump_resume_thread_reply( const struct resume_thread_request *req )
 {
     fprintf( stderr, " count=%d", req->count );
 }
 
-static void dump_debugger_request( struct debugger_request *req )
+static void dump_debugger_request( const struct debugger_request *req )
 {
     fprintf( stderr, " op=%d", req->op );
 }
 
-static void dump_queue_apc_request( struct queue_apc_request *req )
+static void dump_queue_apc_request( const struct queue_apc_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " func=%p,", req->func );
     fprintf( stderr, " param=%p", req->param );
 }
 
-static void dump_get_apcs_request( struct get_apcs_request *req )
+static void dump_get_apcs_request( const struct get_apcs_request *req )
 {
 }
 
-static void dump_get_apcs_reply( struct get_apcs_request *req )
+static void dump_get_apcs_reply( const struct get_apcs_request *req )
 {
     fprintf( stderr, " count=%d,", req->count );
     fprintf( stderr, " apcs=" );
     dump_varargs_get_apcs_reply( req );
 }
 
-static void dump_close_handle_request( struct close_handle_request *req )
+static void dump_close_handle_request( const struct close_handle_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_get_handle_info_request( struct get_handle_info_request *req )
+static void dump_get_handle_info_request( const struct get_handle_info_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_get_handle_info_reply( struct get_handle_info_request *req )
+static void dump_get_handle_info_reply( const struct get_handle_info_request *req )
 {
     fprintf( stderr, " flags=%d", req->flags );
 }
 
-static void dump_set_handle_info_request( struct set_handle_info_request *req )
+static void dump_set_handle_info_request( const struct set_handle_info_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " flags=%d,", req->flags );
     fprintf( stderr, " mask=%d", req->mask );
 }
 
-static void dump_dup_handle_request( struct dup_handle_request *req )
+static void dump_dup_handle_request( const struct dup_handle_request *req )
 {
     fprintf( stderr, " src_process=%d,", req->src_process );
     fprintf( stderr, " src_handle=%d,", req->src_handle );
@@ -302,24 +402,24 @@
     fprintf( stderr, " options=%d", req->options );
 }
 
-static void dump_dup_handle_reply( struct dup_handle_request *req )
+static void dump_dup_handle_reply( const struct dup_handle_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_open_process_request( struct open_process_request *req )
+static void dump_open_process_request( const struct open_process_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d", req->inherit );
 }
 
-static void dump_open_process_reply( struct open_process_request *req )
+static void dump_open_process_reply( const struct open_process_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_select_request( struct select_request *req )
+static void dump_select_request( const struct select_request *req )
 {
     fprintf( stderr, " count=%d,", req->count );
     fprintf( stderr, " flags=%d,", req->flags );
@@ -328,12 +428,12 @@
     dump_varargs_select_request( req );
 }
 
-static void dump_select_reply( struct select_request *req )
+static void dump_select_reply( const struct select_request *req )
 {
     fprintf( stderr, " signaled=%d", req->signaled );
 }
 
-static void dump_create_event_request( struct create_event_request *req )
+static void dump_create_event_request( const struct create_event_request *req )
 {
     fprintf( stderr, " manual_reset=%d,", req->manual_reset );
     fprintf( stderr, " initial_state=%d,", req->initial_state );
@@ -342,18 +442,18 @@
     dump_unicode_string( req->name );
 }
 
-static void dump_create_event_reply( struct create_event_request *req )
+static void dump_create_event_reply( const struct create_event_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_event_op_request( struct event_op_request *req )
+static void dump_event_op_request( const struct event_op_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " op=%d", req->op );
 }
 
-static void dump_open_event_request( struct open_event_request *req )
+static void dump_open_event_request( const struct open_event_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
@@ -361,12 +461,12 @@
     dump_unicode_string( req->name );
 }
 
-static void dump_open_event_reply( struct open_event_request *req )
+static void dump_open_event_reply( const struct open_event_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_create_mutex_request( struct create_mutex_request *req )
+static void dump_create_mutex_request( const struct create_mutex_request *req )
 {
     fprintf( stderr, " owned=%d,", req->owned );
     fprintf( stderr, " inherit=%d,", req->inherit );
@@ -374,17 +474,17 @@
     dump_unicode_string( req->name );
 }
 
-static void dump_create_mutex_reply( struct create_mutex_request *req )
+static void dump_create_mutex_reply( const struct create_mutex_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_release_mutex_request( struct release_mutex_request *req )
+static void dump_release_mutex_request( const struct release_mutex_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_open_mutex_request( struct open_mutex_request *req )
+static void dump_open_mutex_request( const struct open_mutex_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
@@ -392,12 +492,12 @@
     dump_unicode_string( req->name );
 }
 
-static void dump_open_mutex_reply( struct open_mutex_request *req )
+static void dump_open_mutex_reply( const struct open_mutex_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_create_semaphore_request( struct create_semaphore_request *req )
+static void dump_create_semaphore_request( const struct create_semaphore_request *req )
 {
     fprintf( stderr, " initial=%08x,", req->initial );
     fprintf( stderr, " max=%08x,", req->max );
@@ -406,23 +506,23 @@
     dump_unicode_string( req->name );
 }
 
-static void dump_create_semaphore_reply( struct create_semaphore_request *req )
+static void dump_create_semaphore_reply( const struct create_semaphore_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_release_semaphore_request( struct release_semaphore_request *req )
+static void dump_release_semaphore_request( const struct release_semaphore_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " count=%08x", req->count );
 }
 
-static void dump_release_semaphore_reply( struct release_semaphore_request *req )
+static void dump_release_semaphore_reply( const struct release_semaphore_request *req )
 {
     fprintf( stderr, " prev_count=%08x", req->prev_count );
 }
 
-static void dump_open_semaphore_request( struct open_semaphore_request *req )
+static void dump_open_semaphore_request( const struct open_semaphore_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
@@ -430,12 +530,12 @@
     dump_unicode_string( req->name );
 }
 
-static void dump_open_semaphore_reply( struct open_semaphore_request *req )
+static void dump_open_semaphore_reply( const struct open_semaphore_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_create_file_request( struct create_file_request *req )
+static void dump_create_file_request( const struct create_file_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
@@ -445,32 +545,32 @@
     fprintf( stderr, " name=\"%s\"", req->name );
 }
 
-static void dump_create_file_reply( struct create_file_request *req )
+static void dump_create_file_reply( const struct create_file_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_alloc_file_handle_request( struct alloc_file_handle_request *req )
+static void dump_alloc_file_handle_request( const struct alloc_file_handle_request *req )
 {
     fprintf( stderr, " access=%08x", req->access );
 }
 
-static void dump_alloc_file_handle_reply( struct alloc_file_handle_request *req )
+static void dump_alloc_file_handle_reply( const struct alloc_file_handle_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_get_read_fd_request( struct get_read_fd_request *req )
+static void dump_get_read_fd_request( const struct get_read_fd_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_get_write_fd_request( struct get_write_fd_request *req )
+static void dump_get_write_fd_request( const struct get_write_fd_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_set_file_pointer_request( struct set_file_pointer_request *req )
+static void dump_set_file_pointer_request( const struct set_file_pointer_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " low=%d,", req->low );
@@ -478,35 +578,35 @@
     fprintf( stderr, " whence=%d", req->whence );
 }
 
-static void dump_set_file_pointer_reply( struct set_file_pointer_request *req )
+static void dump_set_file_pointer_reply( const struct set_file_pointer_request *req )
 {
     fprintf( stderr, " new_low=%d,", req->new_low );
     fprintf( stderr, " new_high=%d", req->new_high );
 }
 
-static void dump_truncate_file_request( struct truncate_file_request *req )
+static void dump_truncate_file_request( const struct truncate_file_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_set_file_time_request( struct set_file_time_request *req )
+static void dump_set_file_time_request( const struct set_file_time_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " access_time=%ld,", req->access_time );
     fprintf( stderr, " write_time=%ld", req->write_time );
 }
 
-static void dump_flush_file_request( struct flush_file_request *req )
+static void dump_flush_file_request( const struct flush_file_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_get_file_info_request( struct get_file_info_request *req )
+static void dump_get_file_info_request( const struct get_file_info_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_get_file_info_reply( struct get_file_info_request *req )
+static void dump_get_file_info_reply( const struct get_file_info_request *req )
 {
     fprintf( stderr, " type=%d,", req->type );
     fprintf( stderr, " attr=%d,", req->attr );
@@ -520,7 +620,7 @@
     fprintf( stderr, " serial=%08x", req->serial );
 }
 
-static void dump_lock_file_request( struct lock_file_request *req )
+static void dump_lock_file_request( const struct lock_file_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " offset_low=%08x,", req->offset_low );
@@ -529,7 +629,7 @@
     fprintf( stderr, " count_high=%08x", req->count_high );
 }
 
-static void dump_unlock_file_request( struct unlock_file_request *req )
+static void dump_unlock_file_request( const struct unlock_file_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " offset_low=%08x,", req->offset_low );
@@ -538,18 +638,18 @@
     fprintf( stderr, " count_high=%08x", req->count_high );
 }
 
-static void dump_create_pipe_request( struct create_pipe_request *req )
+static void dump_create_pipe_request( const struct create_pipe_request *req )
 {
     fprintf( stderr, " inherit=%d", req->inherit );
 }
 
-static void dump_create_pipe_reply( struct create_pipe_request *req )
+static void dump_create_pipe_reply( const struct create_pipe_request *req )
 {
     fprintf( stderr, " handle_read=%d,", req->handle_read );
     fprintf( stderr, " handle_write=%d", req->handle_write );
 }
 
-static void dump_create_socket_request( struct create_socket_request *req )
+static void dump_create_socket_request( const struct create_socket_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
@@ -558,38 +658,38 @@
     fprintf( stderr, " protocol=%d", req->protocol );
 }
 
-static void dump_create_socket_reply( struct create_socket_request *req )
+static void dump_create_socket_reply( const struct create_socket_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_accept_socket_request( struct accept_socket_request *req )
+static void dump_accept_socket_request( const struct accept_socket_request *req )
 {
     fprintf( stderr, " lhandle=%d,", req->lhandle );
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d", req->inherit );
 }
 
-static void dump_accept_socket_reply( struct accept_socket_request *req )
+static void dump_accept_socket_reply( const struct accept_socket_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_set_socket_event_request( struct set_socket_event_request *req )
+static void dump_set_socket_event_request( const struct set_socket_event_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " mask=%08x,", req->mask );
     fprintf( stderr, " event=%d", req->event );
 }
 
-static void dump_get_socket_event_request( struct get_socket_event_request *req )
+static void dump_get_socket_event_request( const struct get_socket_event_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " service=%d,", req->service );
     fprintf( stderr, " s_event=%d", req->s_event );
 }
 
-static void dump_get_socket_event_reply( struct get_socket_event_request *req )
+static void dump_get_socket_event_reply( const struct get_socket_event_request *req )
 {
     fprintf( stderr, " mask=%08x,", req->mask );
     fprintf( stderr, " pmask=%08x,", req->pmask );
@@ -598,7 +698,7 @@
     dump_varargs_get_socket_event_reply( req );
 }
 
-static void dump_enable_socket_event_request( struct enable_socket_event_request *req )
+static void dump_enable_socket_event_request( const struct enable_socket_event_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " mask=%08x,", req->mask );
@@ -606,59 +706,59 @@
     fprintf( stderr, " cstate=%08x", req->cstate );
 }
 
-static void dump_alloc_console_request( struct alloc_console_request *req )
+static void dump_alloc_console_request( const struct alloc_console_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d", req->inherit );
 }
 
-static void dump_alloc_console_reply( struct alloc_console_request *req )
+static void dump_alloc_console_reply( const struct alloc_console_request *req )
 {
     fprintf( stderr, " handle_in=%d,", req->handle_in );
     fprintf( stderr, " handle_out=%d", req->handle_out );
 }
 
-static void dump_free_console_request( struct free_console_request *req )
+static void dump_free_console_request( const struct free_console_request *req )
 {
     fprintf( stderr, " dummy=%d", req->dummy );
 }
 
-static void dump_open_console_request( struct open_console_request *req )
+static void dump_open_console_request( const struct open_console_request *req )
 {
     fprintf( stderr, " output=%d,", req->output );
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d", req->inherit );
 }
 
-static void dump_open_console_reply( struct open_console_request *req )
+static void dump_open_console_reply( const struct open_console_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_set_console_fd_request( struct set_console_fd_request *req )
+static void dump_set_console_fd_request( const struct set_console_fd_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " file_handle=%d,", req->file_handle );
     fprintf( stderr, " pid=%d", req->pid );
 }
 
-static void dump_get_console_mode_request( struct get_console_mode_request *req )
+static void dump_get_console_mode_request( const struct get_console_mode_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_get_console_mode_reply( struct get_console_mode_request *req )
+static void dump_get_console_mode_reply( const struct get_console_mode_request *req )
 {
     fprintf( stderr, " mode=%d", req->mode );
 }
 
-static void dump_set_console_mode_request( struct set_console_mode_request *req )
+static void dump_set_console_mode_request( const struct set_console_mode_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " mode=%d", req->mode );
 }
 
-static void dump_set_console_info_request( struct set_console_info_request *req )
+static void dump_set_console_info_request( const struct set_console_info_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " mask=%d,", req->mask );
@@ -667,12 +767,12 @@
     fprintf( stderr, " title=\"%s\"", req->title );
 }
 
-static void dump_get_console_info_request( struct get_console_info_request *req )
+static void dump_get_console_info_request( const struct get_console_info_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_get_console_info_reply( struct get_console_info_request *req )
+static void dump_get_console_info_reply( const struct get_console_info_request *req )
 {
     fprintf( stderr, " cursor_size=%d,", req->cursor_size );
     fprintf( stderr, " cursor_visible=%d,", req->cursor_visible );
@@ -680,41 +780,41 @@
     fprintf( stderr, " title=\"%s\"", req->title );
 }
 
-static void dump_write_console_input_request( struct write_console_input_request *req )
+static void dump_write_console_input_request( const struct write_console_input_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " count=%d", req->count );
 }
 
-static void dump_write_console_input_reply( struct write_console_input_request *req )
+static void dump_write_console_input_reply( const struct write_console_input_request *req )
 {
     fprintf( stderr, " written=%d", req->written );
 }
 
-static void dump_read_console_input_request( struct read_console_input_request *req )
+static void dump_read_console_input_request( const struct read_console_input_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " count=%d,", req->count );
     fprintf( stderr, " flush=%d", req->flush );
 }
 
-static void dump_read_console_input_reply( struct read_console_input_request *req )
+static void dump_read_console_input_reply( const struct read_console_input_request *req )
 {
     fprintf( stderr, " read=%d", req->read );
 }
 
-static void dump_create_change_notification_request( struct create_change_notification_request *req )
+static void dump_create_change_notification_request( const struct create_change_notification_request *req )
 {
     fprintf( stderr, " subtree=%d,", req->subtree );
     fprintf( stderr, " filter=%d", req->filter );
 }
 
-static void dump_create_change_notification_reply( struct create_change_notification_request *req )
+static void dump_create_change_notification_reply( const struct create_change_notification_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_create_mapping_request( struct create_mapping_request *req )
+static void dump_create_mapping_request( const struct create_mapping_request *req )
 {
     fprintf( stderr, " size_high=%d,", req->size_high );
     fprintf( stderr, " size_low=%d,", req->size_low );
@@ -725,12 +825,12 @@
     dump_unicode_string( req->name );
 }
 
-static void dump_create_mapping_reply( struct create_mapping_request *req )
+static void dump_create_mapping_reply( const struct create_mapping_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_open_mapping_request( struct open_mapping_request *req )
+static void dump_open_mapping_request( const struct open_mapping_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
@@ -738,107 +838,109 @@
     dump_unicode_string( req->name );
 }
 
-static void dump_open_mapping_reply( struct open_mapping_request *req )
+static void dump_open_mapping_reply( const struct open_mapping_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_get_mapping_info_request( struct get_mapping_info_request *req )
+static void dump_get_mapping_info_request( const struct get_mapping_info_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_get_mapping_info_reply( struct get_mapping_info_request *req )
+static void dump_get_mapping_info_reply( const struct get_mapping_info_request *req )
 {
     fprintf( stderr, " size_high=%d,", req->size_high );
     fprintf( stderr, " size_low=%d,", req->size_low );
     fprintf( stderr, " protect=%d", req->protect );
 }
 
-static void dump_create_device_request( struct create_device_request *req )
+static void dump_create_device_request( const struct create_device_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
     fprintf( stderr, " id=%d", req->id );
 }
 
-static void dump_create_device_reply( struct create_device_request *req )
+static void dump_create_device_reply( const struct create_device_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_create_snapshot_request( struct create_snapshot_request *req )
+static void dump_create_snapshot_request( const struct create_snapshot_request *req )
 {
     fprintf( stderr, " inherit=%d,", req->inherit );
     fprintf( stderr, " flags=%d", req->flags );
 }
 
-static void dump_create_snapshot_reply( struct create_snapshot_request *req )
+static void dump_create_snapshot_reply( const struct create_snapshot_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_next_process_request( struct next_process_request *req )
+static void dump_next_process_request( const struct next_process_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " reset=%d", req->reset );
 }
 
-static void dump_next_process_reply( struct next_process_request *req )
+static void dump_next_process_reply( const struct next_process_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " threads=%d,", req->threads );
     fprintf( stderr, " priority=%d", req->priority );
 }
 
-static void dump_wait_debug_event_request( struct wait_debug_event_request *req )
+static void dump_wait_debug_event_request( const struct wait_debug_event_request *req )
 {
     fprintf( stderr, " timeout=%d", req->timeout );
 }
 
-static void dump_wait_debug_event_reply( struct wait_debug_event_request *req )
+static void dump_wait_debug_event_reply( const struct wait_debug_event_request *req )
 {
-    fprintf( stderr, " code=%d,", req->code );
     fprintf( stderr, " pid=%p,", req->pid );
-    fprintf( stderr, " tid=%p", req->tid );
+    fprintf( stderr, " tid=%p,", req->tid );
+    fprintf( stderr, " event=" );
+    dump_debug_event_t( &req->event );
 }
 
-static void dump_send_debug_event_request( struct send_debug_event_request *req )
+static void dump_send_debug_event_request( const struct send_debug_event_request *req )
 {
-    fprintf( stderr, " code=%d", req->code );
+    fprintf( stderr, " event=" );
+    dump_debug_event_t( &req->event );
 }
 
-static void dump_send_debug_event_reply( struct send_debug_event_request *req )
+static void dump_send_debug_event_reply( const struct send_debug_event_request *req )
 {
     fprintf( stderr, " status=%d", req->status );
 }
 
-static void dump_continue_debug_event_request( struct continue_debug_event_request *req )
+static void dump_continue_debug_event_request( const struct continue_debug_event_request *req )
 {
     fprintf( stderr, " pid=%p,", req->pid );
     fprintf( stderr, " tid=%p,", req->tid );
     fprintf( stderr, " status=%d", req->status );
 }
 
-static void dump_debug_process_request( struct debug_process_request *req )
+static void dump_debug_process_request( const struct debug_process_request *req )
 {
     fprintf( stderr, " pid=%p", req->pid );
 }
 
-static void dump_read_process_memory_request( struct read_process_memory_request *req )
+static void dump_read_process_memory_request( const struct read_process_memory_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " addr=%p,", req->addr );
     fprintf( stderr, " len=%d", req->len );
 }
 
-static void dump_read_process_memory_reply( struct read_process_memory_request *req )
+static void dump_read_process_memory_reply( const struct read_process_memory_request *req )
 {
     fprintf( stderr, " data=" );
     dump_varargs_read_process_memory_reply( req );
 }
 
-static void dump_write_process_memory_request( struct write_process_memory_request *req )
+static void dump_write_process_memory_request( const struct write_process_memory_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " addr=%p,", req->addr );
@@ -849,72 +951,72 @@
     dump_varargs_write_process_memory_request( req );
 }
 
-static void dump_create_key_request( struct create_key_request *req )
+static void dump_create_key_request( const struct create_key_request *req )
 {
     fprintf( stderr, " parent=%d,", req->parent );
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " options=%08x,", req->options );
     fprintf( stderr, " modif=%ld,", req->modif );
     fprintf( stderr, " name=" );
-    dump_unicode_string( req->name );
+    dump_path_t( &req->name );
     fprintf( stderr, "," );
     fprintf( stderr, " class=" );
     dump_unicode_string( req->class );
 }
 
-static void dump_create_key_reply( struct create_key_request *req )
+static void dump_create_key_reply( const struct create_key_request *req )
 {
     fprintf( stderr, " hkey=%d,", req->hkey );
     fprintf( stderr, " created=%d", req->created );
 }
 
-static void dump_open_key_request( struct open_key_request *req )
+static void dump_open_key_request( const struct open_key_request *req )
 {
     fprintf( stderr, " parent=%d,", req->parent );
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " name=" );
-    dump_unicode_string( req->name );
+    dump_path_t( &req->name );
 }
 
-static void dump_open_key_reply( struct open_key_request *req )
+static void dump_open_key_reply( const struct open_key_request *req )
 {
     fprintf( stderr, " hkey=%d", req->hkey );
 }
 
-static void dump_delete_key_request( struct delete_key_request *req )
+static void dump_delete_key_request( const struct delete_key_request *req )
 {
     fprintf( stderr, " hkey=%d,", req->hkey );
     fprintf( stderr, " name=" );
-    dump_unicode_string( req->name );
+    dump_path_t( &req->name );
 }
 
-static void dump_close_key_request( struct close_key_request *req )
+static void dump_close_key_request( const struct close_key_request *req )
 {
     fprintf( stderr, " hkey=%d", req->hkey );
 }
 
-static void dump_enum_key_request( struct enum_key_request *req )
+static void dump_enum_key_request( const struct enum_key_request *req )
 {
     fprintf( stderr, " hkey=%d,", req->hkey );
     fprintf( stderr, " index=%d", req->index );
 }
 
-static void dump_enum_key_reply( struct enum_key_request *req )
+static void dump_enum_key_reply( const struct enum_key_request *req )
 {
     fprintf( stderr, " modif=%ld,", req->modif );
     fprintf( stderr, " name=" );
-    dump_unicode_string( req->name );
+    dump_path_t( &req->name );
     fprintf( stderr, "," );
     fprintf( stderr, " class=" );
     dump_unicode_string( req->class );
 }
 
-static void dump_query_key_info_request( struct query_key_info_request *req )
+static void dump_query_key_info_request( const struct query_key_info_request *req )
 {
     fprintf( stderr, " hkey=%d", req->hkey );
 }
 
-static void dump_query_key_info_reply( struct query_key_info_request *req )
+static void dump_query_key_info_reply( const struct query_key_info_request *req )
 {
     fprintf( stderr, " subkeys=%d,", req->subkeys );
     fprintf( stderr, " max_subkey=%d,", req->max_subkey );
@@ -924,32 +1026,32 @@
     fprintf( stderr, " max_data=%d,", req->max_data );
     fprintf( stderr, " modif=%ld,", req->modif );
     fprintf( stderr, " name=" );
-    dump_unicode_string( req->name );
+    dump_path_t( &req->name );
     fprintf( stderr, "," );
     fprintf( stderr, " class=" );
     dump_unicode_string( req->class );
 }
 
-static void dump_set_key_value_request( struct set_key_value_request *req )
+static void dump_set_key_value_request( const struct set_key_value_request *req )
 {
     fprintf( stderr, " hkey=%d,", req->hkey );
     fprintf( stderr, " type=%d,", req->type );
     fprintf( stderr, " len=%d,", req->len );
     fprintf( stderr, " name=" );
-    dump_unicode_string( req->name );
+    dump_path_t( &req->name );
     fprintf( stderr, "," );
     fprintf( stderr, " data=" );
     dump_varargs_set_key_value_request( req );
 }
 
-static void dump_get_key_value_request( struct get_key_value_request *req )
+static void dump_get_key_value_request( const struct get_key_value_request *req )
 {
     fprintf( stderr, " hkey=%d,", req->hkey );
     fprintf( stderr, " name=" );
     dump_unicode_string( req->name );
 }
 
-static void dump_get_key_value_reply( struct get_key_value_request *req )
+static void dump_get_key_value_reply( const struct get_key_value_request *req )
 {
     fprintf( stderr, " type=%d,", req->type );
     fprintf( stderr, " len=%d,", req->len );
@@ -957,52 +1059,52 @@
     dump_varargs_get_key_value_reply( req );
 }
 
-static void dump_enum_key_value_request( struct enum_key_value_request *req )
+static void dump_enum_key_value_request( const struct enum_key_value_request *req )
 {
     fprintf( stderr, " hkey=%d,", req->hkey );
     fprintf( stderr, " index=%d", req->index );
 }
 
-static void dump_enum_key_value_reply( struct enum_key_value_request *req )
+static void dump_enum_key_value_reply( const struct enum_key_value_request *req )
 {
     fprintf( stderr, " type=%d,", req->type );
     fprintf( stderr, " len=%d,", req->len );
     fprintf( stderr, " name=" );
-    dump_unicode_string( req->name );
+    dump_path_t( &req->name );
     fprintf( stderr, "," );
     fprintf( stderr, " data=" );
     dump_varargs_enum_key_value_reply( req );
 }
 
-static void dump_delete_key_value_request( struct delete_key_value_request *req )
+static void dump_delete_key_value_request( const struct delete_key_value_request *req )
 {
     fprintf( stderr, " hkey=%d,", req->hkey );
     fprintf( stderr, " name=" );
-    dump_unicode_string( req->name );
+    dump_path_t( &req->name );
 }
 
-static void dump_load_registry_request( struct load_registry_request *req )
+static void dump_load_registry_request( const struct load_registry_request *req )
 {
     fprintf( stderr, " hkey=%d,", req->hkey );
     fprintf( stderr, " file=%d,", req->file );
     fprintf( stderr, " name=" );
-    dump_unicode_string( req->name );
+    dump_path_t( &req->name );
 }
 
-static void dump_save_registry_request( struct save_registry_request *req )
+static void dump_save_registry_request( const struct save_registry_request *req )
 {
     fprintf( stderr, " hkey=%d,", req->hkey );
     fprintf( stderr, " file=%d", req->file );
 }
 
-static void dump_set_registry_levels_request( struct set_registry_levels_request *req )
+static void dump_set_registry_levels_request( const struct set_registry_levels_request *req )
 {
     fprintf( stderr, " current=%d,", req->current );
     fprintf( stderr, " saving=%d,", req->saving );
     fprintf( stderr, " version=%d", req->version );
 }
 
-static void dump_create_timer_request( struct create_timer_request *req )
+static void dump_create_timer_request( const struct create_timer_request *req )
 {
     fprintf( stderr, " inherit=%d,", req->inherit );
     fprintf( stderr, " manual=%d,", req->manual );
@@ -1010,12 +1112,12 @@
     dump_unicode_string( req->name );
 }
 
-static void dump_create_timer_reply( struct create_timer_request *req )
+static void dump_create_timer_reply( const struct create_timer_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_open_timer_request( struct open_timer_request *req )
+static void dump_open_timer_request( const struct open_timer_request *req )
 {
     fprintf( stderr, " access=%08x,", req->access );
     fprintf( stderr, " inherit=%d,", req->inherit );
@@ -1023,12 +1125,12 @@
     dump_unicode_string( req->name );
 }
 
-static void dump_open_timer_reply( struct open_timer_request *req )
+static void dump_open_timer_reply( const struct open_timer_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
-static void dump_set_timer_request( struct set_timer_request *req )
+static void dump_set_timer_request( const struct set_timer_request *req )
 {
     fprintf( stderr, " handle=%d,", req->handle );
     fprintf( stderr, " sec=%d,", req->sec );
@@ -1038,11 +1140,31 @@
     fprintf( stderr, " arg=%p", req->arg );
 }
 
-static void dump_cancel_timer_request( struct cancel_timer_request *req )
+static void dump_cancel_timer_request( const struct cancel_timer_request *req )
 {
     fprintf( stderr, " handle=%d", req->handle );
 }
 
+static void dump_get_thread_context_request( const struct get_thread_context_request *req )
+{
+    fprintf( stderr, " handle=%d,", req->handle );
+    fprintf( stderr, " flags=%08x", req->flags );
+}
+
+static void dump_get_thread_context_reply( const struct get_thread_context_request *req )
+{
+    fprintf( stderr, " context=" );
+    dump_context( &req->context );
+}
+
+static void dump_set_thread_context_request( const struct set_thread_context_request *req )
+{
+    fprintf( stderr, " handle=%d,", req->handle );
+    fprintf( stderr, " flags=%08x,", req->flags );
+    fprintf( stderr, " context=" );
+    dump_context( &req->context );
+}
+
 static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
     (dump_func)dump_new_process_request,
     (dump_func)dump_new_thread_request,
@@ -1134,6 +1256,8 @@
     (dump_func)dump_open_timer_request,
     (dump_func)dump_set_timer_request,
     (dump_func)dump_cancel_timer_request,
+    (dump_func)dump_get_thread_context_request,
+    (dump_func)dump_set_thread_context_request,
 };
 
 static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
@@ -1227,6 +1351,8 @@
     (dump_func)dump_open_timer_reply,
     (dump_func)0,
     (dump_func)0,
+    (dump_func)dump_get_thread_context_reply,
+    (dump_func)0,
 };
 
 static const char * const req_names[REQ_NB_REQUESTS] = {
@@ -1320,6 +1446,8 @@
     "open_timer",
     "set_timer",
     "cancel_timer",
+    "get_thread_context",
+    "set_thread_context",
 };
 
 /* ### make_requests end ### */