Skip queue cleanups if queue has been destroyed already.
[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     process_destroy              /* destroy */
57 };
58
59 /* process startup info */
60
61 struct startup_info
62 {
63     struct object       obj;          /* object header */
64     int                 inherit_all;  /* inherit all handles from parent */
65     int                 create_flags; /* creation flags */
66     int                 start_flags;  /* flags from startup info */
67     handle_t            hstdin;       /* handle for stdin */
68     handle_t            hstdout;      /* handle for stdout */
69     handle_t            hstderr;      /* handle for stderr */
70     int                 cmd_show;     /* main window show mode */
71     struct file        *exe_file;     /* file handle for main exe */
72     char               *filename;     /* file name for main exe */
73     struct thread      *owner;        /* owner thread (the one that created the new process) */
74     struct process     *process;      /* created process */
75     struct thread      *thread;       /* created thread */
76 };
77
78 static void startup_info_dump( struct object *obj, int verbose );
79 static int startup_info_signaled( struct object *obj, struct thread *thread );
80 static void startup_info_destroy( struct object *obj );
81
82 static const struct object_ops startup_info_ops =
83 {
84     sizeof(struct startup_info),   /* size */
85     startup_info_dump,             /* dump */
86     add_queue,                     /* add_queue */
87     remove_queue,                  /* remove_queue */
88     startup_info_signaled,         /* signaled */
89     no_satisfied,                  /* satisfied */
90     NULL,                          /* get_poll_events */
91     NULL,                          /* poll_event */
92     no_get_fd,                     /* get_fd */
93     no_flush,                      /* flush */
94     no_get_file_info,              /* get_file_info */
95     startup_info_destroy           /* destroy */
96 };
97
98
99 /* set the console and stdio handles for a newly created process */
100 static int set_process_console( struct process *process, struct process *parent,
101                                 struct startup_info *info, struct init_process_request *req )
102 {
103     if (process->create_flags & CREATE_NEW_CONSOLE)
104     {
105         /* let the process init do the allocation */
106         return 1;
107     }
108     else if (parent && !(process->create_flags & DETACHED_PROCESS))
109     {
110         /* FIXME: some better error checking should be done...
111          * like if hConOut and hConIn are console handles, then they should be on the same
112          * physical console
113          */
114         inherit_console( parent, process,
115                          (info->inherit_all || (info->start_flags & STARTF_USESTDHANDLES)) ?
116                          info->hstdin : 0 );
117     }
118     if (parent)
119     {
120         if (!info->inherit_all && !(info->start_flags & STARTF_USESTDHANDLES))
121         {
122             /* duplicate the handle from the parent into this process */
123             req->hstdin  = duplicate_handle( parent, info->hstdin, process,
124                                              0, TRUE, DUPLICATE_SAME_ACCESS );
125             req->hstdout = duplicate_handle( parent, info->hstdout, process,
126                                              0, TRUE, DUPLICATE_SAME_ACCESS );
127             req->hstderr = duplicate_handle( parent, info->hstderr, process,
128                                              0, TRUE, DUPLICATE_SAME_ACCESS );
129         }
130         else
131         {
132             req->hstdin  = info->hstdin;
133             req->hstdout = info->hstdout;
134             req->hstderr = info->hstderr;
135         }
136     }
137     else
138     {
139         if (process->console)
140         {
141             req->hstdin  = alloc_handle( process, process->console,
142                                          GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
143             req->hstdout = alloc_handle( process, process->console->active,
144                                          GENERIC_READ | GENERIC_WRITE, 1 );
145             req->hstderr = alloc_handle( process, process->console->active,
146                                          GENERIC_READ | GENERIC_WRITE, 1 );
147         }
148         else
149         {
150             /* no parent, let the caller decide what to do */
151             req->hstdin = req->hstdout = req->hstderr = 0;
152         }
153     }
154     /* some handles above may have been invalid; this is not an error */
155     if (get_error() == STATUS_INVALID_HANDLE) clear_error();
156     return 1;
157 }
158
159 /* create a new process and its main thread */
160 struct thread *create_process( int fd )
161 {
162     struct process *process;
163     struct thread *thread = NULL;
164     int request_pipe[2];
165
166     if (!(process = alloc_object( &process_ops, fd ))) return NULL;
167     process->next            = NULL;
168     process->prev            = NULL;
169     process->parent          = NULL;
170     process->thread_list     = NULL;
171     process->debugger        = NULL;
172     process->handles         = NULL;
173     process->exit_code       = STILL_ACTIVE;
174     process->running_threads = 0;
175     process->priority        = NORMAL_PRIORITY_CLASS;
176     process->affinity        = 1;
177     process->suspend         = 0;
178     process->create_flags    = 0;
179     process->console         = NULL;
180     process->init_event      = NULL;
181     process->idle_event      = NULL;
182     process->queue           = NULL;
183     process->atom_table      = NULL;
184     process->ldt_copy        = NULL;
185     process->exe.next        = NULL;
186     process->exe.prev        = NULL;
187     process->exe.file        = NULL;
188     process->exe.dbg_offset  = 0;
189     process->exe.dbg_size    = 0;
190
191     gettimeofday( &process->start_time, NULL );
192     if ((process->next = first_process) != NULL) process->next->prev = process;
193     first_process = process;
194
195     /* create the init done event */
196     if (!(process->init_event = create_event( NULL, 0, 1, 0 ))) goto error;
197
198     /* create the main thread */
199     if (pipe( request_pipe ) == -1)
200     {
201         file_set_error();
202         goto error;
203     }
204     send_client_fd( process, request_pipe[1], 0 );
205     close( request_pipe[1] );
206     if (!(thread = create_thread( request_pipe[0], process ))) goto error;
207
208     set_select_events( &process->obj, POLLIN );  /* start listening to events */
209     release_object( process );
210     return thread;
211
212  error:
213     if (thread) release_object( thread );
214     release_object( process );
215     return NULL;
216 }
217
218 /* initialize the current process and fill in the request */
219 static void init_process( int ppid, struct init_process_request *req )
220 {
221     struct process *process = current->process;
222     struct thread *parent_thread = get_thread_from_pid( ppid );
223     struct process *parent = NULL;
224     struct startup_info *info = NULL;
225
226     if (parent_thread)
227     {
228         parent = parent_thread->process;
229         info = parent_thread->info;
230         if (!info)
231         {
232             fatal_protocol_error( current, "init_process: parent but no info\n" );
233             return;
234         }
235         if (info->thread)
236         {
237             fatal_protocol_error( current, "init_process: called twice?\n" );
238             return;
239         }
240         process->parent = (struct process *)grab_object( parent );
241     }
242
243     /* set the process flags */
244     process->create_flags = info ? info->create_flags : 0;
245
246     /* create the handle table */
247     if (parent && info->inherit_all)
248         process->handles = copy_handle_table( process, parent );
249     else
250         process->handles = alloc_handle_table( process, 0 );
251     if (!process->handles) return;
252
253     /* retrieve the main exe file */
254     req->exe_file = 0;
255     if (parent && info->exe_file)
256     {
257         process->exe.file = (struct file *)grab_object( info->exe_file );
258         if (!(req->exe_file = alloc_handle( process, process->exe.file, GENERIC_READ, 0 )))
259             return;
260     }
261
262     /* set the process console */
263     if (!set_process_console( process, parent, info, req )) return;
264
265     if (parent)
266     {
267         /* attach to the debugger if requested */
268         if (process->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
269             set_process_debugger( process, parent_thread );
270         else if (parent && parent->debugger && !(parent->create_flags & DEBUG_ONLY_THIS_PROCESS))
271             set_process_debugger( process, parent->debugger );
272     }
273
274     /* thread will be actually suspended in init_done */
275     if (process->create_flags & CREATE_SUSPENDED) current->suspend++;
276
277     if (info)
278     {
279         size_t size = strlen(info->filename);
280         if (size > get_req_data_size(req)) size = get_req_data_size(req);
281         req->start_flags = info->start_flags;
282         req->cmd_show    = info->cmd_show;
283         memcpy( get_req_data(req), info->filename, size );
284         set_req_data_size( req, size );
285         info->process = (struct process *)grab_object( process );
286         info->thread  = (struct thread *)grab_object( current );
287         wake_up( &info->obj, 0 );
288     }
289     else
290     {
291         req->start_flags  = STARTF_USESTDHANDLES;
292         req->cmd_show     = 0;
293         set_req_data_size( req, 0 );
294     }
295     req->create_flags = process->create_flags;
296     req->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 static void kill_console_processes( struct process *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->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     /* close the processes using process as renderer, if any */
469     kill_console_processes( process, 0 );
470
471     while (process->exe.next)
472     {
473         struct process_dll *dll = process->exe.next;
474         process->exe.next = dll->next;
475         if (dll->file) release_object( dll->file );
476         free( dll );
477     }
478     if (process->exe.file) release_object( process->exe.file );
479     process->exe.file = NULL;
480     wake_up( &process->obj, 0 );
481     if (!--running_processes)
482     {
483         /* last process died, close global handles */
484         close_global_handles();
485         /* this will cause the select loop to terminate */
486         if (!persistent_server) close_master_socket();
487     }
488 }
489
490 /* add a thread to a process running threads list */
491 void add_process_thread( struct process *process, struct thread *thread )
492 {
493     thread->proc_next = process->thread_list;
494     thread->proc_prev = NULL;
495     if (thread->proc_next) thread->proc_next->proc_prev = thread;
496     process->thread_list = thread;
497     if (!process->running_threads++) running_processes++;
498     grab_object( thread );
499 }
500
501 /* remove a thread from a process running threads list */
502 void remove_process_thread( struct process *process, struct thread *thread )
503 {
504     assert( process->running_threads > 0 );
505     assert( process->thread_list );
506
507     if (thread->proc_next) thread->proc_next->proc_prev = thread->proc_prev;
508     if (thread->proc_prev) thread->proc_prev->proc_next = thread->proc_next;
509     else process->thread_list = thread->proc_next;
510
511     if (!--process->running_threads)
512     {
513         /* we have removed the last running thread, exit the process */
514         process->exit_code = thread->exit_code;
515         generate_debug_event( thread, EXIT_PROCESS_DEBUG_EVENT, process );
516         process_killed( process );
517     }
518     else generate_debug_event( thread, EXIT_THREAD_DEBUG_EVENT, thread );
519     release_object( thread );
520 }
521
522 /* suspend all the threads of a process */
523 void suspend_process( struct process *process )
524 {
525     if (!process->suspend++)
526     {
527         struct thread *thread = process->thread_list;
528         for (; thread; thread = thread->proc_next)
529         {
530             if (!thread->suspend) stop_thread( thread );
531         }
532     }
533 }
534
535 /* resume all the threads of a process */
536 void resume_process( struct process *process )
537 {
538     assert (process->suspend > 0);
539     if (!--process->suspend)
540     {
541         struct thread *thread = process->thread_list;
542         for (; thread; thread = thread->proc_next)
543         {
544             if (!thread->suspend) continue_thread( thread );
545         }
546     }
547 }
548
549 /* kill a process on the spot */
550 void kill_process( struct process *process, struct thread *skip, int exit_code )
551 {
552     struct thread *thread = process->thread_list;
553
554     while (thread)
555     {
556         struct thread *next = thread->proc_next;
557         thread->exit_code = exit_code;
558         if (thread != skip) kill_thread( thread, 1 );
559         thread = next;
560     }
561 }
562
563 /* kill all processes being debugged by a given thread */
564 void kill_debugged_processes( struct thread *debugger, int exit_code )
565 {
566     for (;;)  /* restart from the beginning of the list every time */
567     {
568         struct process *process = first_process;
569         /* find the first process being debugged by 'debugger' and still running */
570         while (process && (process->debugger != debugger || !process->running_threads))
571             process = process->next;
572         if (!process) return;
573         process->debugger = NULL;
574         kill_process( process, NULL, exit_code );
575     }
576 }
577
578
579 /* get all information about a process */
580 static void get_process_info( struct process *process, struct get_process_info_request *req )
581 {
582     req->pid              = process;
583     req->debugged         = (process->debugger != 0);
584     req->exit_code        = process->exit_code;
585     req->priority         = process->priority;
586     req->process_affinity = process->affinity;
587     req->system_affinity  = 1;
588 }
589
590 /* set all information about a process */
591 static void set_process_info( struct process *process,
592                               struct set_process_info_request *req )
593 {
594     if (req->mask & SET_PROCESS_INFO_PRIORITY)
595         process->priority = req->priority;
596     if (req->mask & SET_PROCESS_INFO_AFFINITY)
597     {
598         if (req->affinity != 1) set_error( STATUS_INVALID_PARAMETER );
599         else process->affinity = req->affinity;
600     }
601 }
602
603 /* read data from a process memory space */
604 /* len is the total size (in ints), max is the size we can actually store in the output buffer */
605 /* we read the total size in all cases to check for permissions */
606 static void read_process_memory( struct process *process, const int *addr,
607                                  size_t len, size_t max, int *dest )
608 {
609     struct thread *thread = process->thread_list;
610
611     if ((unsigned int)addr % sizeof(int))  /* address must be aligned */
612     {
613         set_error( STATUS_INVALID_PARAMETER );
614         return;
615     }
616     if (!thread)  /* process is dead */
617     {
618         set_error( STATUS_ACCESS_DENIED );
619         return;
620     }
621     if (suspend_for_ptrace( thread ))
622     {
623         while (len > 0 && max)
624         {
625             if (read_thread_int( thread, addr++, dest++ ) == -1) goto done;
626             max--;
627             len--;
628         }
629         /* check the rest for read permission */
630         if (len > 0)
631         {
632             int dummy, page = get_page_size() / sizeof(int);
633             while (len >= page)
634             {
635                 addr += page;
636                 len -= page;
637                 if (read_thread_int( thread, addr - 1, &dummy ) == -1) goto done;
638             }
639             if (len && (read_thread_int( thread, addr + len - 1, &dummy ) == -1)) goto done;
640         }
641     done:
642         resume_thread( thread );
643     }
644 }
645
646 /* write data to a process memory space */
647 /* len is the total size (in ints), max is the size we can actually read from the input buffer */
648 /* we check the total size for write permissions */
649 static void write_process_memory( struct process *process, int *addr, size_t len,
650                                   size_t max, unsigned int first_mask,
651                                   unsigned int last_mask, const int *src )
652 {
653     struct thread *thread = process->thread_list;
654
655     if (!len || ((unsigned int)addr % sizeof(int)))  /* address must be aligned */
656     {
657         set_error( STATUS_INVALID_PARAMETER );
658         return;
659     }
660     if (!thread)  /* process is dead */
661     {
662         set_error( STATUS_ACCESS_DENIED );
663         return;
664     }
665     if (suspend_for_ptrace( thread ))
666     {
667         /* first word is special */
668         if (len > 1)
669         {
670             if (write_thread_int( thread, addr++, *src++, first_mask ) == -1) goto done;
671             len--;
672             max--;
673         }
674         else last_mask &= first_mask;
675
676         while (len > 1 && max)
677         {
678             if (write_thread_int( thread, addr++, *src++, ~0 ) == -1) goto done;
679             max--;
680             len--;
681         }
682
683         if (max)
684         {
685             /* last word is special too */
686             if (write_thread_int( thread, addr, *src, last_mask ) == -1) goto done;
687         }
688         else
689         {
690             /* check the rest for write permission */
691             int page = get_page_size() / sizeof(int);
692             while (len >= page)
693             {
694                 addr += page;
695                 len -= page;
696                 if (write_thread_int( thread, addr - 1, 0, 0 ) == -1) goto done;
697             }
698             if (len && (write_thread_int( thread, addr + len - 1, 0, 0 ) == -1)) goto done;
699         }
700     done:
701         resume_thread( thread );
702     }
703 }
704
705 /* take a snapshot of currently running processes */
706 struct process_snapshot *process_snap( int *count )
707 {
708     struct process_snapshot *snapshot, *ptr;
709     struct process *process;
710     if (!running_processes) return NULL;
711     if (!(snapshot = mem_alloc( sizeof(*snapshot) * running_processes )))
712         return NULL;
713     ptr = snapshot;
714     for (process = first_process; process; process = process->next)
715     {
716         if (!process->running_threads) continue;
717         ptr->process  = process;
718         ptr->threads  = process->running_threads;
719         ptr->count    = process->obj.refcount;
720         ptr->priority = process->priority;
721         grab_object( process );
722         ptr++;
723     }
724     *count = running_processes;
725     return snapshot;
726 }
727
728 /* take a snapshot of the modules of a process */
729 struct module_snapshot *module_snap( struct process *process, int *count )
730 {
731     struct module_snapshot *snapshot, *ptr;
732     struct process_dll *dll;
733     int total = 0;
734
735     for (dll = &process->exe; dll; dll = dll->next) total++;
736     if (!(snapshot = mem_alloc( sizeof(*snapshot) * total ))) return NULL;
737
738     for (ptr = snapshot, dll = &process->exe; dll; dll = dll->next, ptr++)
739     {
740         ptr->base = dll->base;
741     }
742     *count = total;
743     return snapshot;
744 }
745
746
747 /* create a new process */
748 DECL_HANDLER(new_process)
749 {
750     size_t len = get_req_data_size( req );
751     struct startup_info *info;
752
753     if (current->info)
754     {
755         fatal_protocol_error( current, "new_process: another process is being created\n" );
756         return;
757     }
758
759     /* build the startup info for a new process */
760     if (!(info = alloc_object( &startup_info_ops, -1 ))) return;
761     info->inherit_all  = req->inherit_all;
762     info->create_flags = req->create_flags;
763     info->start_flags  = req->start_flags;
764     info->hstdin       = req->hstdin;
765     info->hstdout      = req->hstdout;
766     info->hstderr      = req->hstderr;
767     info->cmd_show     = req->cmd_show;
768     info->exe_file     = NULL;
769     info->filename     = NULL;
770     info->owner        = (struct thread *)grab_object( current );
771     info->process      = NULL;
772     info->thread       = NULL;
773
774     if (req->exe_file &&
775         !(info->exe_file = get_file_obj( current->process, req->exe_file, GENERIC_READ )))
776         goto done;
777
778     if (!(info->filename = mem_alloc( len + 1 ))) goto done;
779
780     memcpy( info->filename, get_req_data(req), len );
781     info->filename[len] = 0;
782     current->info = info;
783     req->info = alloc_handle( current->process, info, SYNCHRONIZE, FALSE );
784
785  done:
786     release_object( info );
787 }
788
789 /* Retrieve information about a newly started process */
790 DECL_HANDLER(get_new_process_info)
791 {
792     struct startup_info *info;
793
794     req->event = 0;
795
796     if ((info = (struct startup_info *)get_handle_obj( current->process, req->info,
797                                                        0, &startup_info_ops )))
798     {
799         req->pid = get_process_id( info->process );
800         req->tid = get_thread_id( info->thread );
801         req->phandle = alloc_handle( current->process, info->process,
802                                      PROCESS_ALL_ACCESS, req->pinherit );
803         req->thandle = alloc_handle( current->process, info->thread,
804                                      THREAD_ALL_ACCESS, req->tinherit );
805         if (info->process->init_event)
806             req->event = alloc_handle( current->process, info->process->init_event,
807                                        EVENT_ALL_ACCESS, 0 );
808         release_object( info );
809     }
810     else
811     {
812         req->pid     = 0;
813         req->tid     = 0;
814         req->phandle = 0;
815         req->thandle = 0;
816     }
817 }
818
819 /* initialize a new process */
820 DECL_HANDLER(init_process)
821 {
822     if (!current->unix_pid)
823     {
824         fatal_protocol_error( current, "init_process: init_thread not called yet\n" );
825         return;
826     }
827     current->process->ldt_copy  = req->ldt_copy;
828     init_process( req->ppid, req );
829 }
830
831 /* signal the end of the process initialization */
832 DECL_HANDLER(init_process_done)
833 {
834     struct file *file = NULL;
835     struct process *process = current->process;
836
837     if (!process->init_event)
838     {
839         fatal_protocol_error( current, "init_process_done: no event\n" );
840         return;
841     }
842     process->exe.base = req->module;
843     process->exe.name = req->name;
844
845     if (req->exe_file) file = get_file_obj( current->process, req->exe_file, GENERIC_READ );
846     if (process->exe.file) release_object( process->exe.file );
847     process->exe.file = file;
848
849     generate_startup_debug_events( current->process, req->entry );
850     set_event( process->init_event );
851     release_object( process->init_event );
852     process->init_event = NULL;
853     if (req->gui) process->idle_event = create_event( NULL, 0, 1, 0 );
854     if (current->suspend + current->process->suspend > 0) stop_thread( current );
855     req->debugged = (current->process->debugger != 0);
856 }
857
858 /* open a handle to a process */
859 DECL_HANDLER(open_process)
860 {
861     struct process *process = get_process_from_id( req->pid );
862     req->handle = 0;
863     if (process)
864     {
865         req->handle = alloc_handle( current->process, process, req->access, req->inherit );
866         release_object( process );
867     }
868 }
869
870 /* terminate a process */
871 DECL_HANDLER(terminate_process)
872 {
873     struct process *process;
874
875     if ((process = get_process_from_handle( req->handle, PROCESS_TERMINATE )))
876     {
877         req->self = (current->process == process);
878         kill_process( process, current, req->exit_code );
879         release_object( process );
880     }
881 }
882
883 /* fetch information about a process */
884 DECL_HANDLER(get_process_info)
885 {
886     struct process *process;
887
888     if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
889     {
890         get_process_info( process, req );
891         release_object( process );
892     }
893 }
894
895 /* set information about a process */
896 DECL_HANDLER(set_process_info)
897 {
898     struct process *process;
899
900     if ((process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION )))
901     {
902         set_process_info( process, req );
903         release_object( process );
904     }
905 }
906
907 /* read data from a process address space */
908 DECL_HANDLER(read_process_memory)
909 {
910     struct process *process;
911
912     if ((process = get_process_from_handle( req->handle, PROCESS_VM_READ )))
913     {
914         size_t maxlen = get_req_data_size(req) / sizeof(int);
915         read_process_memory( process, req->addr, req->len, maxlen, get_req_data(req) );
916         release_object( process );
917     }
918 }
919
920 /* write data to a process address space */
921 DECL_HANDLER(write_process_memory)
922 {
923     struct process *process;
924
925     if ((process = get_process_from_handle( req->handle, PROCESS_VM_WRITE )))
926     {
927         size_t maxlen = get_req_data_size(req) / sizeof(int);
928         write_process_memory( process, req->addr, req->len, maxlen,
929                               req->first_mask, req->last_mask, get_req_data(req) );
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     req->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             req->event = alloc_handle( current->process, process->idle_event,
972                                        EVENT_ALL_ACCESS, 0 );
973         release_object( process );
974     }
975 }