Save the registry before exiting on a SIGTERM.
[wine] / server / process.c
1 /*
2  * Server-side process management
3  *
4  * Copyright (C) 1998 Alexandre Julliard
5  */
6
7 #include "config.h"
8
9 #include <assert.h>
10 #include <errno.h>
11 #include <limits.h>
12 #include <signal.h>
13 #include <string.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <sys/time.h>
17 #ifdef HAVE_SYS_SOCKET_H
18 # include <sys/socket.h>
19 #endif
20 #include <unistd.h>
21
22 #include "winbase.h"
23 #include "winnt.h"
24
25 #include "handle.h"
26 #include "process.h"
27 #include "thread.h"
28 #include "request.h"
29 #include "console.h"
30
31 /* process structure */
32
33 static struct process *first_process;
34 static int running_processes;
35
36 /* process operations */
37
38 static void process_dump( struct object *obj, int verbose );
39 static int process_signaled( struct object *obj, struct thread *thread );
40 static void process_poll_event( struct object *obj, int event );
41 static void process_destroy( struct object *obj );
42
43 static const struct object_ops process_ops =
44 {
45     sizeof(struct process),      /* size */
46     process_dump,                /* dump */
47     add_queue,                   /* add_queue */
48     remove_queue,                /* remove_queue */
49     process_signaled,            /* signaled */
50     no_satisfied,                /* satisfied */
51     NULL,                        /* get_poll_events */
52     process_poll_event,          /* poll_event */
53     no_get_fd,                   /* get_fd */
54     no_flush,                    /* flush */
55     no_get_file_info,            /* get_file_info */
56     NULL,                        /* queue_async */
57     process_destroy              /* destroy */
58 };
59
60 /* process startup info */
61
62 struct startup_info
63 {
64     struct object       obj;          /* object header */
65     int                 inherit_all;  /* inherit all handles from parent */
66     int                 create_flags; /* creation flags */
67     int                 start_flags;  /* flags from startup info */
68     handle_t            hstdin;       /* handle for stdin */
69     handle_t            hstdout;      /* handle for stdout */
70     handle_t            hstderr;      /* handle for stderr */
71     int                 cmd_show;     /* main window show mode */
72     struct file        *exe_file;     /* file handle for main exe */
73     char               *filename;     /* file name for main exe */
74     struct thread      *owner;        /* owner thread (the one that created the new process) */
75     struct process     *process;      /* created process */
76     struct thread      *thread;       /* created thread */
77 };
78
79 static void startup_info_dump( struct object *obj, int verbose );
80 static int startup_info_signaled( struct object *obj, struct thread *thread );
81 static void startup_info_destroy( struct object *obj );
82
83 static const struct object_ops startup_info_ops =
84 {
85     sizeof(struct startup_info),   /* size */
86     startup_info_dump,             /* dump */
87     add_queue,                     /* add_queue */
88     remove_queue,                  /* remove_queue */
89     startup_info_signaled,         /* signaled */
90     no_satisfied,                  /* satisfied */
91     NULL,                          /* get_poll_events */
92     NULL,                          /* poll_event */
93     no_get_fd,                     /* get_fd */
94     no_flush,                      /* flush */
95     no_get_file_info,              /* get_file_info */
96     NULL,                        /* queue_async */
97     startup_info_destroy           /* destroy */
98 };
99
100
101 /* set the console and stdio handles for a newly created process */
102 static int set_process_console( struct process *process, struct thread *parent_thread,
103                                 struct startup_info *info, struct init_process_reply *reply )
104 {
105     if (process->create_flags & CREATE_NEW_CONSOLE)
106     {
107         /* let the process init do the allocation */
108         return 1;
109     }
110     else if (parent_thread && !(process->create_flags & DETACHED_PROCESS))
111     {
112         /* FIXME: some better error checking should be done...
113          * like if hConOut and hConIn are console handles, then they should be on the same
114          * physical console
115          */
116         inherit_console( parent_thread, process,
117                          (info->inherit_all || (info->start_flags & STARTF_USESTDHANDLES)) ?
118                          info->hstdin : 0 );
119     }
120     if (parent_thread)
121     {
122         if (!info->inherit_all && !(info->start_flags & STARTF_USESTDHANDLES))
123         {
124             /* duplicate the handle from the parent into this process */
125             reply->hstdin  = duplicate_handle( parent_thread->process, info->hstdin, process,
126                                                0, TRUE, DUPLICATE_SAME_ACCESS );
127             reply->hstdout = duplicate_handle( parent_thread->process, info->hstdout, process,
128                                                0, TRUE, DUPLICATE_SAME_ACCESS );
129             reply->hstderr = duplicate_handle( parent_thread->process, info->hstderr, process,
130                                                0, TRUE, DUPLICATE_SAME_ACCESS );
131         }
132         else
133         {
134             reply->hstdin  = info->hstdin;
135             reply->hstdout = info->hstdout;
136             reply->hstderr = info->hstderr;
137         }
138     }
139     else
140     {
141         if (process->console)
142         {
143             reply->hstdin  = alloc_handle( process, process->console,
144                                            GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
145             reply->hstdout = alloc_handle( process, process->console->active,
146                                            GENERIC_READ | GENERIC_WRITE, 1 );
147             reply->hstderr = alloc_handle( process, process->console->active,
148                                            GENERIC_READ | GENERIC_WRITE, 1 );
149         }
150         else
151         {
152             /* no parent, let the caller decide what to do */
153             reply->hstdin = reply->hstdout = reply->hstderr = 0;
154         }
155     }
156     /* some handles above may have been invalid; this is not an error */
157     if (get_error() == STATUS_INVALID_HANDLE) clear_error();
158     return 1;
159 }
160
161 /* create a new process and its main thread */
162 struct thread *create_process( int fd )
163 {
164     struct process *process;
165     struct thread *thread = NULL;
166     int request_pipe[2];
167
168     if (!(process = alloc_object( &process_ops, fd ))) return NULL;
169     process->next            = NULL;
170     process->prev            = NULL;
171     process->parent          = NULL;
172     process->thread_list     = NULL;
173     process->debugger        = NULL;
174     process->handles         = NULL;
175     process->exit_code       = STILL_ACTIVE;
176     process->running_threads = 0;
177     process->priority        = NORMAL_PRIORITY_CLASS;
178     process->affinity        = 1;
179     process->suspend         = 0;
180     process->create_flags    = 0;
181     process->console         = NULL;
182     process->init_event      = NULL;
183     process->idle_event      = NULL;
184     process->queue           = NULL;
185     process->atom_table      = NULL;
186     process->ldt_copy        = NULL;
187     process->exe.next        = NULL;
188     process->exe.prev        = NULL;
189     process->exe.file        = NULL;
190     process->exe.dbg_offset  = 0;
191     process->exe.dbg_size    = 0;
192
193     gettimeofday( &process->start_time, NULL );
194     if ((process->next = first_process) != NULL) process->next->prev = process;
195     first_process = process;
196
197     /* create the init done event */
198     if (!(process->init_event = create_event( NULL, 0, 1, 0 ))) goto error;
199
200     /* create the main thread */
201     if (pipe( request_pipe ) == -1)
202     {
203         file_set_error();
204         goto error;
205     }
206     send_client_fd( process, request_pipe[1], 0 );
207     close( request_pipe[1] );
208     if (!(thread = create_thread( request_pipe[0], process ))) goto error;
209
210     set_select_events( &process->obj, POLLIN );  /* start listening to events */
211     release_object( process );
212     return thread;
213
214  error:
215     if (thread) release_object( thread );
216     release_object( process );
217     return NULL;
218 }
219
220 /* initialize the current process and fill in the request */
221 static void init_process( int ppid, struct init_process_reply *reply )
222 {
223     struct process *process = current->process;
224     struct thread *parent_thread = get_thread_from_pid( ppid );
225     struct process *parent = NULL;
226     struct startup_info *info = NULL;
227
228     if (parent_thread)
229     {
230         parent = parent_thread->process;
231         info = parent_thread->info;
232         if (!info)
233         {
234             fatal_protocol_error( current, "init_process: parent but no info\n" );
235             return;
236         }
237         if (info->thread)
238         {
239             fatal_protocol_error( current, "init_process: called twice?\n" );
240             return;
241         }
242         process->parent = (struct process *)grab_object( parent );
243     }
244
245     /* set the process flags */
246     process->create_flags = info ? info->create_flags : 0;
247
248     /* create the handle table */
249     if (parent && info->inherit_all)
250         process->handles = copy_handle_table( process, parent );
251     else
252         process->handles = alloc_handle_table( process, 0 );
253     if (!process->handles) return;
254
255     /* retrieve the main exe file */
256     reply->exe_file = 0;
257     if (parent && info->exe_file)
258     {
259         process->exe.file = (struct file *)grab_object( info->exe_file );
260         if (!(reply->exe_file = alloc_handle( process, process->exe.file, GENERIC_READ, 0 )))
261             return;
262     }
263
264     /* set the process console */
265     if (!set_process_console( process, parent_thread, info, reply )) return;
266
267     if (parent)
268     {
269         /* attach to the debugger if requested */
270         if (process->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
271             set_process_debugger( process, parent_thread );
272         else if (parent && parent->debugger && !(parent->create_flags & DEBUG_ONLY_THIS_PROCESS))
273             set_process_debugger( process, parent->debugger );
274     }
275
276     /* thread will be actually suspended in init_done */
277     if (process->create_flags & CREATE_SUSPENDED) current->suspend++;
278
279     if (info)
280     {
281         size_t size = strlen(info->filename);
282         if (size > get_reply_max_size()) size = get_reply_max_size();
283         reply->start_flags = info->start_flags;
284         reply->cmd_show    = info->cmd_show;
285         set_reply_data( info->filename, size );
286         info->process = (struct process *)grab_object( process );
287         info->thread  = (struct thread *)grab_object( current );
288         wake_up( &info->obj, 0 );
289     }
290     else
291     {
292         reply->start_flags  = STARTF_USESTDHANDLES;
293         reply->cmd_show     = 0;
294     }
295     reply->create_flags = process->create_flags;
296     reply->server_start = server_start_ticks;
297 }
298
299 /* destroy a process when its refcount is 0 */
300 static void process_destroy( struct object *obj )
301 {
302     struct process *process = (struct process *)obj;
303     assert( obj->ops == &process_ops );
304
305     /* we can't have a thread remaining */
306     assert( !process->thread_list );
307     if (process->console) release_object( process->console );
308     if (process->parent) release_object( process->parent );
309     if (process->next) process->next->prev = process->prev;
310     if (process->prev) process->prev->next = process->next;
311     else first_process = process->next;
312     if (process->init_event) release_object( process->init_event );
313     if (process->idle_event) release_object( process->idle_event );
314     if (process->queue) release_object( process->queue );
315     if (process->atom_table) release_object( process->atom_table );
316     if (process->exe.file) release_object( process->exe.file );
317 }
318
319 /* dump a process on stdout for debugging purposes */
320 static void process_dump( struct object *obj, int verbose )
321 {
322     struct process *process = (struct process *)obj;
323     assert( obj->ops == &process_ops );
324
325     fprintf( stderr, "Process next=%p prev=%p handles=%p\n",
326              process->next, process->prev, process->handles );
327 }
328
329 static int process_signaled( struct object *obj, struct thread *thread )
330 {
331     struct process *process = (struct process *)obj;
332     return !process->running_threads;
333 }
334
335
336 static void process_poll_event( struct object *obj, int event )
337 {
338     struct process *process = (struct process *)obj;
339     assert( obj->ops == &process_ops );
340
341     if (event & (POLLERR | POLLHUP)) set_select_events( obj, -1 );
342     else if (event & POLLIN) receive_fd( process );
343 }
344
345 static void startup_info_destroy( struct object *obj )
346 {
347     struct startup_info *info = (struct startup_info *)obj;
348     assert( obj->ops == &startup_info_ops );
349     if (info->filename) free( info->filename );
350     if (info->exe_file) release_object( info->exe_file );
351     if (info->process) release_object( info->process );
352     if (info->thread) release_object( info->thread );
353     if (info->owner)
354     {
355         info->owner->info = NULL;
356         release_object( info->owner );
357     }
358 }
359
360 static void startup_info_dump( struct object *obj, int verbose )
361 {
362     struct startup_info *info = (struct startup_info *)obj;
363     assert( obj->ops == &startup_info_ops );
364
365     fprintf( stderr, "Startup info flags=%x in=%d out=%d err=%d name='%s'\n",
366              info->start_flags, info->hstdin, info->hstdout, info->hstderr, info->filename );
367 }
368
369 static int startup_info_signaled( struct object *obj, struct thread *thread )
370 {
371     struct startup_info *info = (struct startup_info *)obj;
372     return (info->thread != NULL);
373 }
374
375
376 /* get a process from an id (and increment the refcount) */
377 struct process *get_process_from_id( void *id )
378 {
379     struct process *p = first_process;
380     while (p && (p != id)) p = p->next;
381     if (p) grab_object( p );
382     else set_error( STATUS_INVALID_PARAMETER );
383     return p;
384 }
385
386 /* get a process from a handle (and increment the refcount) */
387 struct process *get_process_from_handle( handle_t handle, unsigned int access )
388 {
389     return (struct process *)get_handle_obj( current->process, handle,
390                                              access, &process_ops );
391 }
392
393 /* add a dll to a process list */
394 static struct process_dll *process_load_dll( struct process *process, struct file *file,
395                                              void *base )
396 {
397     struct process_dll *dll;
398
399     /* make sure we don't already have one with the same base address */
400     for (dll = process->exe.next; dll; dll = dll->next) if (dll->base == base)
401     {
402         set_error( STATUS_INVALID_PARAMETER );
403         return NULL;
404     }
405
406     if ((dll = mem_alloc( sizeof(*dll) )))
407     {
408         dll->prev = &process->exe;
409         dll->file = NULL;
410         dll->base = base;
411         if (file) dll->file = (struct file *)grab_object( file );
412         if ((dll->next = process->exe.next)) dll->next->prev = dll;
413         process->exe.next = dll;
414     }
415     return dll;
416 }
417
418 /* remove a dll from a process list */
419 static void process_unload_dll( struct process *process, void *base )
420 {
421     struct process_dll *dll;
422
423     for (dll = process->exe.next; dll; dll = dll->next)
424     {
425         if (dll->base == base)
426         {
427             if (dll->file) release_object( dll->file );
428             if (dll->next) dll->next->prev = dll->prev;
429             if (dll->prev) dll->prev->next = dll->next;
430             free( dll );
431             generate_debug_event( current, UNLOAD_DLL_DEBUG_EVENT, base );
432             return;
433         }
434     }
435     set_error( STATUS_INVALID_PARAMETER );
436 }
437
438 /* kill all processes being attached to a console renderer */
439 void kill_console_processes( struct thread *renderer, int exit_code )
440 {
441     for (;;)  /* restart from the beginning of the list every time */
442     {
443         struct process *process = first_process;
444
445         /* find the first process being attached to 'renderer' and still running */
446         while (process &&
447                (process == renderer->process || !process->console ||
448                 process->console->renderer != renderer || !process->running_threads))
449         {
450             process = process->next;
451         }
452         if (!process) break;
453         kill_process( process, NULL, exit_code );
454     }
455 }
456
457 /* a process has been killed (i.e. its last thread died) */
458 static void process_killed( struct process *process )
459 {
460     assert( !process->thread_list );
461     gettimeofday( &process->end_time, NULL );
462     if (process->handles) release_object( process->handles );
463     process->handles = NULL;
464
465     /* close the console attached to this process, if any */
466     free_console( process );
467
468     while (process->exe.next)
469     {
470         struct process_dll *dll = process->exe.next;
471         process->exe.next = dll->next;
472         if (dll->file) release_object( dll->file );
473         free( dll );
474     }
475     if (process->exe.file) release_object( process->exe.file );
476     process->exe.file = NULL;
477     wake_up( &process->obj, 0 );
478     if (!--running_processes)
479     {
480         /* last process died, close global handles */
481         close_global_handles();
482         /* this will cause the select loop to terminate */
483         if (!persistent_server) close_master_socket();
484     }
485 }
486
487 /* add a thread to a process running threads list */
488 void add_process_thread( struct process *process, struct thread *thread )
489 {
490     thread->proc_next = process->thread_list;
491     thread->proc_prev = NULL;
492     if (thread->proc_next) thread->proc_next->proc_prev = thread;
493     process->thread_list = thread;
494     if (!process->running_threads++) running_processes++;
495     grab_object( thread );
496 }
497
498 /* remove a thread from a process running threads list */
499 void remove_process_thread( struct process *process, struct thread *thread )
500 {
501     assert( process->running_threads > 0 );
502     assert( process->thread_list );
503
504     if (thread->proc_next) thread->proc_next->proc_prev = thread->proc_prev;
505     if (thread->proc_prev) thread->proc_prev->proc_next = thread->proc_next;
506     else process->thread_list = thread->proc_next;
507
508     if (!--process->running_threads)
509     {
510         /* we have removed the last running thread, exit the process */
511         process->exit_code = thread->exit_code;
512         generate_debug_event( thread, EXIT_PROCESS_DEBUG_EVENT, process );
513         process_killed( process );
514     }
515     else generate_debug_event( thread, EXIT_THREAD_DEBUG_EVENT, thread );
516     release_object( thread );
517 }
518
519 /* suspend all the threads of a process */
520 void suspend_process( struct process *process )
521 {
522     if (!process->suspend++)
523     {
524         struct thread *thread = process->thread_list;
525         for (; thread; thread = thread->proc_next)
526         {
527             if (!thread->suspend) stop_thread( thread );
528         }
529     }
530 }
531
532 /* resume all the threads of a process */
533 void resume_process( struct process *process )
534 {
535     assert (process->suspend > 0);
536     if (!--process->suspend)
537     {
538         struct thread *thread = process->thread_list;
539         for (; thread; thread = thread->proc_next)
540         {
541             if (!thread->suspend) continue_thread( thread );
542         }
543     }
544 }
545
546 /* kill a process on the spot */
547 void kill_process( struct process *process, struct thread *skip, int exit_code )
548 {
549     struct thread *thread = process->thread_list;
550
551     while (thread)
552     {
553         struct thread *next = thread->proc_next;
554         thread->exit_code = exit_code;
555         if (thread != skip) kill_thread( thread, 1 );
556         thread = next;
557     }
558 }
559
560 /* kill all processes being debugged by a given thread */
561 void kill_debugged_processes( struct thread *debugger, int exit_code )
562 {
563     for (;;)  /* restart from the beginning of the list every time */
564     {
565         struct process *process = first_process;
566         /* find the first process being debugged by 'debugger' and still running */
567         while (process && (process->debugger != debugger || !process->running_threads))
568             process = process->next;
569         if (!process) return;
570         process->debugger = NULL;
571         kill_process( process, NULL, exit_code );
572     }
573 }
574
575
576 /* get all information about a process */
577 static void get_process_info( struct process *process, struct get_process_info_reply *reply )
578 {
579     reply->pid              = process;
580     reply->debugged         = (process->debugger != 0);
581     reply->exit_code        = process->exit_code;
582     reply->priority         = process->priority;
583     reply->process_affinity = process->affinity;
584     reply->system_affinity  = 1;
585 }
586
587 /* set all information about a process */
588 static void set_process_info( struct process *process,
589                               const struct set_process_info_request *req )
590 {
591     if (req->mask & SET_PROCESS_INFO_PRIORITY)
592         process->priority = req->priority;
593     if (req->mask & SET_PROCESS_INFO_AFFINITY)
594     {
595         if (req->affinity != 1) set_error( STATUS_INVALID_PARAMETER );
596         else process->affinity = req->affinity;
597     }
598 }
599
600 /* read data from a process memory space */
601 /* len is the total size (in ints) */
602 static int read_process_memory( struct process *process, const int *addr, size_t len, int *dest )
603 {
604     struct thread *thread = process->thread_list;
605
606     assert( !((unsigned int)addr % sizeof(int)) );  /* address must be aligned */
607
608     if (!thread)  /* process is dead */
609     {
610         set_error( STATUS_ACCESS_DENIED );
611         return 0;
612     }
613     if (suspend_for_ptrace( thread ))
614     {
615         while (len > 0)
616         {
617             if (read_thread_int( thread, addr++, dest++ ) == -1) break;
618             len--;
619         }
620         resume_thread( thread );
621     }
622     return !len;
623 }
624
625 /* make sure we can write to the whole address range */
626 /* len is the total size (in ints) */
627 static int check_process_write_access( struct thread *thread, int *addr, size_t len )
628 {
629     int page = get_page_size() / sizeof(int);
630
631     for (;;)
632     {
633         if (write_thread_int( thread, addr, 0, 0 ) == -1) return 0;
634         if (len <= page) break;
635         addr += page;
636         len -= page;
637     }
638     return (write_thread_int( thread, addr + len - 1, 0, 0 ) != -1);
639 }
640
641 /* write data to a process memory space */
642 /* len is the total size (in ints), max is the size we can actually read from the input buffer */
643 /* we check the total size for write permissions */
644 static void write_process_memory( struct process *process, int *addr, size_t len,
645                                   unsigned int first_mask, unsigned int last_mask, const int *src )
646 {
647     struct thread *thread = process->thread_list;
648
649     assert( !((unsigned int)addr % sizeof(int) ));  /* address must be aligned */
650
651     if (!thread)  /* process is dead */
652     {
653         set_error( STATUS_ACCESS_DENIED );
654         return;
655     }
656     if (suspend_for_ptrace( thread ))
657     {
658         if (!check_process_write_access( thread, addr, len ))
659         {
660             set_error( STATUS_ACCESS_DENIED );
661             return;
662         }
663         /* first word is special */
664         if (len > 1)
665         {
666             if (write_thread_int( thread, addr++, *src++, first_mask ) == -1) goto done;
667             len--;
668         }
669         else last_mask &= first_mask;
670
671         while (len > 1)
672         {
673             if (write_thread_int( thread, addr++, *src++, ~0 ) == -1) goto done;
674             len--;
675         }
676
677         /* last word is special too */
678         if (write_thread_int( thread, addr, *src, last_mask ) == -1) goto done;
679
680     done:
681         resume_thread( thread );
682     }
683 }
684
685 /* take a snapshot of currently running processes */
686 struct process_snapshot *process_snap( int *count )
687 {
688     struct process_snapshot *snapshot, *ptr;
689     struct process *process;
690     if (!running_processes) return NULL;
691     if (!(snapshot = mem_alloc( sizeof(*snapshot) * running_processes )))
692         return NULL;
693     ptr = snapshot;
694     for (process = first_process; process; process = process->next)
695     {
696         if (!process->running_threads) continue;
697         ptr->process  = process;
698         ptr->threads  = process->running_threads;
699         ptr->count    = process->obj.refcount;
700         ptr->priority = process->priority;
701         grab_object( process );
702         ptr++;
703     }
704     *count = running_processes;
705     return snapshot;
706 }
707
708 /* take a snapshot of the modules of a process */
709 struct module_snapshot *module_snap( struct process *process, int *count )
710 {
711     struct module_snapshot *snapshot, *ptr;
712     struct process_dll *dll;
713     int total = 0;
714
715     for (dll = &process->exe; dll; dll = dll->next) total++;
716     if (!(snapshot = mem_alloc( sizeof(*snapshot) * total ))) return NULL;
717
718     for (ptr = snapshot, dll = &process->exe; dll; dll = dll->next, ptr++)
719     {
720         ptr->base = dll->base;
721     }
722     *count = total;
723     return snapshot;
724 }
725
726
727 /* create a new process */
728 DECL_HANDLER(new_process)
729 {
730     size_t len = get_req_data_size();
731     struct startup_info *info;
732
733     if (current->info)
734     {
735         fatal_protocol_error( current, "new_process: another process is being created\n" );
736         return;
737     }
738
739     /* build the startup info for a new process */
740     if (!(info = alloc_object( &startup_info_ops, -1 ))) return;
741     info->inherit_all  = req->inherit_all;
742     info->create_flags = req->create_flags;
743     info->start_flags  = req->start_flags;
744     info->hstdin       = req->hstdin;
745     info->hstdout      = req->hstdout;
746     info->hstderr      = req->hstderr;
747     info->cmd_show     = req->cmd_show;
748     info->exe_file     = NULL;
749     info->filename     = NULL;
750     info->owner        = (struct thread *)grab_object( current );
751     info->process      = NULL;
752     info->thread       = NULL;
753
754     if (req->exe_file &&
755         !(info->exe_file = get_file_obj( current->process, req->exe_file, GENERIC_READ )))
756         goto done;
757
758     if (!(info->filename = mem_alloc( len + 1 ))) goto done;
759
760     memcpy( info->filename, get_req_data(), len );
761     info->filename[len] = 0;
762     current->info = info;
763     reply->info = alloc_handle( current->process, info, SYNCHRONIZE, FALSE );
764
765  done:
766     release_object( info );
767 }
768
769 /* Retrieve information about a newly started process */
770 DECL_HANDLER(get_new_process_info)
771 {
772     struct startup_info *info;
773
774     reply->event = 0;
775
776     if ((info = (struct startup_info *)get_handle_obj( current->process, req->info,
777                                                        0, &startup_info_ops )))
778     {
779         reply->pid = get_process_id( info->process );
780         reply->tid = get_thread_id( info->thread );
781         reply->phandle = alloc_handle( current->process, info->process,
782                                        PROCESS_ALL_ACCESS, req->pinherit );
783         reply->thandle = alloc_handle( current->process, info->thread,
784                                        THREAD_ALL_ACCESS, req->tinherit );
785         if (info->process->init_event)
786             reply->event = alloc_handle( current->process, info->process->init_event,
787                                        EVENT_ALL_ACCESS, 0 );
788         release_object( info );
789     }
790     else
791     {
792         reply->pid     = 0;
793         reply->tid     = 0;
794         reply->phandle = 0;
795         reply->thandle = 0;
796     }
797 }
798
799 /* initialize a new process */
800 DECL_HANDLER(init_process)
801 {
802     if (!current->unix_pid)
803     {
804         fatal_protocol_error( current, "init_process: init_thread not called yet\n" );
805         return;
806     }
807     current->process->ldt_copy  = req->ldt_copy;
808     init_process( req->ppid, reply );
809 }
810
811 /* signal the end of the process initialization */
812 DECL_HANDLER(init_process_done)
813 {
814     struct file *file = NULL;
815     struct process *process = current->process;
816
817     if (!process->init_event)
818     {
819         fatal_protocol_error( current, "init_process_done: no event\n" );
820         return;
821     }
822     process->exe.base = req->module;
823     process->exe.name = req->name;
824
825     if (req->exe_file) file = get_file_obj( current->process, req->exe_file, GENERIC_READ );
826     if (process->exe.file) release_object( process->exe.file );
827     process->exe.file = file;
828
829     generate_startup_debug_events( current->process, req->entry );
830     set_event( process->init_event );
831     release_object( process->init_event );
832     process->init_event = NULL;
833     if (req->gui) process->idle_event = create_event( NULL, 0, 1, 0 );
834     if (current->suspend + current->process->suspend > 0) stop_thread( current );
835     reply->debugged = (current->process->debugger != 0);
836 }
837
838 /* open a handle to a process */
839 DECL_HANDLER(open_process)
840 {
841     struct process *process = get_process_from_id( req->pid );
842     reply->handle = 0;
843     if (process)
844     {
845         reply->handle = alloc_handle( current->process, process, req->access, req->inherit );
846         release_object( process );
847     }
848 }
849
850 /* terminate a process */
851 DECL_HANDLER(terminate_process)
852 {
853     struct process *process;
854
855     if ((process = get_process_from_handle( req->handle, PROCESS_TERMINATE )))
856     {
857         reply->self = (current->process == process);
858         kill_process( process, current, req->exit_code );
859         release_object( process );
860     }
861 }
862
863 /* fetch information about a process */
864 DECL_HANDLER(get_process_info)
865 {
866     struct process *process;
867
868     if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
869     {
870         get_process_info( process, reply );
871         release_object( process );
872     }
873 }
874
875 /* set information about a process */
876 DECL_HANDLER(set_process_info)
877 {
878     struct process *process;
879
880     if ((process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION )))
881     {
882         set_process_info( process, req );
883         release_object( process );
884     }
885 }
886
887 /* read data from a process address space */
888 DECL_HANDLER(read_process_memory)
889 {
890     struct process *process;
891     size_t len = get_reply_max_size();
892
893     if (!(process = get_process_from_handle( req->handle, PROCESS_VM_READ ))) return;
894
895     if (len)
896     {
897         unsigned int start_offset = (unsigned int)req->addr % sizeof(int);
898         unsigned int nb_ints = (len + start_offset + sizeof(int) - 1) / sizeof(int);
899         const int *start = (int *)((char *)req->addr - start_offset);
900         int *buffer = mem_alloc( nb_ints * sizeof(int) );
901         if (buffer)
902         {
903             if (read_process_memory( process, start, nb_ints, buffer ))
904             {
905                 /* move start of requested data to start of buffer */
906                 if (start_offset) memmove( buffer, (char *)buffer + start_offset, len );
907                 set_reply_data_ptr( buffer, len );
908             }
909             else len = 0;
910         }
911     }
912     release_object( process );
913 }
914
915 /* write data to a process address space */
916 DECL_HANDLER(write_process_memory)
917 {
918     struct process *process;
919
920     if ((process = get_process_from_handle( req->handle, PROCESS_VM_WRITE )))
921     {
922         size_t len = get_req_data_size();
923         if ((len % sizeof(int)) || ((unsigned int)req->addr % sizeof(int)))
924             set_error( STATUS_INVALID_PARAMETER );
925         else
926         {
927             if (len) write_process_memory( process, req->addr, len / sizeof(int),
928                                            req->first_mask, req->last_mask, get_req_data() );
929         }
930         release_object( process );
931     }
932 }
933
934 /* notify the server that a dll has been loaded */
935 DECL_HANDLER(load_dll)
936 {
937     struct process_dll *dll;
938     struct file *file = NULL;
939
940     if (req->handle &&
941         !(file = get_file_obj( current->process, req->handle, GENERIC_READ ))) return;
942
943     if ((dll = process_load_dll( current->process, file, req->base )))
944     {
945         dll->dbg_offset = req->dbg_offset;
946         dll->dbg_size   = req->dbg_size;
947         dll->name       = req->name;
948         /* only generate event if initialization is done */
949         if (!current->process->init_event)
950             generate_debug_event( current, LOAD_DLL_DEBUG_EVENT, dll );
951     }
952     if (file) release_object( file );
953 }
954
955 /* notify the server that a dll is being unloaded */
956 DECL_HANDLER(unload_dll)
957 {
958     process_unload_dll( current->process, req->base );
959 }
960
961 /* wait for a process to start waiting on input */
962 /* FIXME: only returns event for now, wait is done in the client */
963 DECL_HANDLER(wait_input_idle)
964 {
965     struct process *process;
966
967     reply->event = 0;
968     if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
969     {
970         if (process->idle_event && process != current->process && process->queue != current->queue)
971             reply->event = alloc_handle( current->process, process->idle_event,
972                                          EVENT_ALL_ACCESS, 0 );
973         release_object( process );
974     }
975 }