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