Fixed pixmap leak with the 1x1 bitmap in memory DCs.
[wine/dcerpc.git] / server / process.c
blobda9d84c6fad7319fbc1cd0a1872c5cf7a399fc78
1 /*
2 * Server-side process management
4 * Copyright (C) 1998 Alexandre Julliard
5 */
7 #include "config.h"
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>
22 #include "winbase.h"
23 #include "winnt.h"
25 #include "handle.h"
26 #include "process.h"
27 #include "thread.h"
28 #include "request.h"
30 /* process structure */
32 static struct process *first_process;
33 static int running_processes;
35 /* process operations */
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 );
41 static const struct object_ops process_ops =
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 */
58 /* set the process creation info */
59 static int set_creation_info( struct process *process, struct new_process_request *req,
60 const char *cmd_line, size_t len )
62 if (!(process->info = mem_alloc( sizeof(*process->info) + len ))) return 0;
63 if (req)
65 /* copy the request structure */
66 memcpy( process->info, req, sizeof(*req) );
68 else /* no request, use defaults */
70 req = process->info;
71 req->pinherit = 0;
72 req->tinherit = 0;
73 req->inherit_all = 0;
74 req->create_flags = CREATE_NEW_CONSOLE;
75 req->start_flags = STARTF_USESTDHANDLES;
76 req->exe_file = -1;
77 req->hstdin = -1;
78 req->hstdout = -1;
79 req->hstderr = -1;
80 req->event = -1;
81 req->cmd_show = 0;
82 req->env_ptr = NULL;
84 memcpy( process->info->cmdline, cmd_line, len );
85 process->info->cmdline[len] = 0;
86 process->create_flags = process->info->create_flags;
87 return 1;
90 /* set the console and stdio handles for a newly created process */
91 static int set_process_console( struct process *process, struct process *parent )
93 struct new_process_request *info = process->info;
95 if (process->create_flags & CREATE_NEW_CONSOLE)
97 if (!alloc_console( process )) return 0;
99 else if (!(process->create_flags & DETACHED_PROCESS))
101 if (parent->console_in) process->console_in = grab_object( parent->console_in );
102 if (parent->console_out) process->console_out = grab_object( parent->console_out );
104 if (parent)
106 if (!info->inherit_all && !(info->start_flags & STARTF_USESTDHANDLES))
108 /* duplicate the handle from the parent into this process */
109 info->hstdin = duplicate_handle( parent, info->hstdin, process,
110 0, TRUE, DUPLICATE_SAME_ACCESS );
111 info->hstdout = duplicate_handle( parent, info->hstdout, process,
112 0, TRUE, DUPLICATE_SAME_ACCESS );
113 info->hstderr = duplicate_handle( parent, info->hstderr, process,
114 0, TRUE, DUPLICATE_SAME_ACCESS );
117 else
119 /* no parent, use handles to the console for stdio */
120 info->hstdin = alloc_handle( process, process->console_in,
121 GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
122 info->hstdout = alloc_handle( process, process->console_out,
123 GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
124 info->hstderr = alloc_handle( process, process->console_out,
125 GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
127 return 1;
130 /* create a new process and its main thread */
131 struct thread *create_process( int fd, struct process *parent,
132 struct new_process_request *req,
133 const char *cmd_line, size_t len )
135 struct process *process;
136 struct thread *thread = NULL;
138 if (!(process = alloc_object( &process_ops, -1 )))
140 close( fd );
141 return NULL;
143 process->next = NULL;
144 process->prev = NULL;
145 process->thread_list = NULL;
146 process->debugger = NULL;
147 process->handles = NULL;
148 process->exit_code = STILL_ACTIVE;
149 process->running_threads = 0;
150 process->priority = NORMAL_PRIORITY_CLASS;
151 process->affinity = 1;
152 process->suspend = 0;
153 process->create_flags = 0;
154 process->console_in = NULL;
155 process->console_out = NULL;
156 process->init_event = NULL;
157 process->info = NULL;
158 process->ldt_copy = NULL;
159 process->ldt_flags = NULL;
160 process->exe.next = NULL;
161 process->exe.prev = NULL;
162 process->exe.file = NULL;
163 process->exe.dbg_offset = 0;
164 process->exe.dbg_size = 0;
165 gettimeofday( &process->start_time, NULL );
166 if ((process->next = first_process) != NULL) process->next->prev = process;
167 first_process = process;
169 /* copy the request structure */
170 if (!set_creation_info( process, req, cmd_line, len )) goto error;
172 if (process->info->inherit_all)
173 process->handles = copy_handle_table( process, parent );
174 else
175 process->handles = alloc_handle_table( process, 0 );
176 if (!process->handles) goto error;
178 /* alloc a handle for the process itself */
179 alloc_handle( process, process, PROCESS_ALL_ACCESS, 0 );
181 /* retrieve the main exe file */
182 if (process->info->exe_file != -1)
184 if (!(process->exe.file = get_file_obj( parent, process->info->exe_file,
185 GENERIC_READ ))) goto error;
186 process->info->exe_file = -1;
189 /* get the init done event */
190 if (process->info->event != -1)
192 if (!(process->init_event = get_event_obj( parent, process->info->event,
193 EVENT_MODIFY_STATE ))) goto error;
196 /* set the process console */
197 if (!set_process_console( process, parent )) goto error;
199 /* create the main thread */
200 if (!(thread = create_thread( fd, process, (process->create_flags & CREATE_SUSPENDED) != 0)))
201 goto error;
203 /* attach to the debugger if requested */
204 if (process->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
205 set_process_debugger( process, current );
206 else if (parent && parent->debugger && !(parent->create_flags & DEBUG_ONLY_THIS_PROCESS))
207 set_process_debugger( process, parent->debugger );
209 release_object( process );
210 return thread;
212 error:
213 close( fd );
214 free_console( process );
215 if (process->handles) release_object( process->handles );
216 release_object( process );
217 return NULL;
220 /* destroy a process when its refcount is 0 */
221 static void process_destroy( struct object *obj )
223 struct process *process = (struct process *)obj;
224 assert( obj->ops == &process_ops );
226 /* we can't have a thread remaining */
227 assert( !process->thread_list );
228 if (process->next) process->next->prev = process->prev;
229 if (process->prev) process->prev->next = process->next;
230 else first_process = process->next;
231 if (process->info) free( process->info );
232 if (process->init_event) release_object( process->init_event );
233 if (process->exe.file) release_object( process->exe.file );
236 /* dump a process on stdout for debugging purposes */
237 static void process_dump( struct object *obj, int verbose )
239 struct process *process = (struct process *)obj;
240 assert( obj->ops == &process_ops );
242 fprintf( stderr, "Process next=%p prev=%p console=%p/%p handles=%p\n",
243 process->next, process->prev, process->console_in, process->console_out,
244 process->handles );
247 static int process_signaled( struct object *obj, struct thread *thread )
249 struct process *process = (struct process *)obj;
250 return !process->running_threads;
254 /* get a process from an id (and increment the refcount) */
255 struct process *get_process_from_id( void *id )
257 struct process *p = first_process;
258 while (p && (p != id)) p = p->next;
259 if (p) grab_object( p );
260 else set_error( STATUS_INVALID_PARAMETER );
261 return p;
264 /* get a process from a handle (and increment the refcount) */
265 struct process *get_process_from_handle( int handle, unsigned int access )
267 return (struct process *)get_handle_obj( current->process, handle,
268 access, &process_ops );
271 /* add a dll to a process list */
272 static struct process_dll *process_load_dll( struct process *process, struct file *file,
273 void *base )
275 struct process_dll *dll;
277 /* make sure we don't already have one with the same base address */
278 for (dll = process->exe.next; dll; dll = dll->next) if (dll->base == base)
280 set_error( STATUS_INVALID_PARAMETER );
281 return NULL;
284 if ((dll = mem_alloc( sizeof(*dll) )))
286 dll->prev = &process->exe;
287 dll->file = NULL;
288 dll->base = base;
289 if (file) dll->file = (struct file *)grab_object( file );
290 if ((dll->next = process->exe.next)) dll->next->prev = dll;
291 process->exe.next = dll;
293 return dll;
296 /* remove a dll from a process list */
297 static void process_unload_dll( struct process *process, void *base )
299 struct process_dll *dll;
301 for (dll = process->exe.next; dll; dll = dll->next)
303 if (dll->base == base)
305 if (dll->file) release_object( dll->file );
306 if (dll->next) dll->next->prev = dll->prev;
307 if (dll->prev) dll->prev->next = dll->next;
308 free( dll );
309 generate_debug_event( current, UNLOAD_DLL_DEBUG_EVENT, base );
310 return;
313 set_error( STATUS_INVALID_PARAMETER );
316 /* a process has been killed (i.e. its last thread died) */
317 static void process_killed( struct process *process )
319 assert( !process->thread_list );
320 gettimeofday( &process->end_time, NULL );
321 release_object( process->handles );
322 process->handles = NULL;
323 free_console( process );
324 while (process->exe.next)
326 struct process_dll *dll = process->exe.next;
327 process->exe.next = dll->next;
328 if (dll->file) release_object( dll->file );
329 free( dll );
331 if (process->exe.file) release_object( process->exe.file );
332 process->exe.file = NULL;
333 wake_up( &process->obj, 0 );
334 if (!--running_processes)
336 /* last process died, close global handles */
337 close_global_handles();
338 /* this will cause the select loop to terminate */
339 if (!persistent_server) close_master_socket();
343 /* add a thread to a process running threads list */
344 void add_process_thread( struct process *process, struct thread *thread )
346 thread->proc_next = process->thread_list;
347 thread->proc_prev = NULL;
348 if (thread->proc_next) thread->proc_next->proc_prev = thread;
349 process->thread_list = thread;
350 if (!process->running_threads++) running_processes++;
351 grab_object( thread );
354 /* remove a thread from a process running threads list */
355 void remove_process_thread( struct process *process, struct thread *thread )
357 assert( process->running_threads > 0 );
358 assert( process->thread_list );
360 if (thread->proc_next) thread->proc_next->proc_prev = thread->proc_prev;
361 if (thread->proc_prev) thread->proc_prev->proc_next = thread->proc_next;
362 else process->thread_list = thread->proc_next;
364 if (!--process->running_threads)
366 /* we have removed the last running thread, exit the process */
367 process->exit_code = thread->exit_code;
368 generate_debug_event( thread, EXIT_PROCESS_DEBUG_EVENT, process );
369 process_killed( process );
371 else generate_debug_event( thread, EXIT_THREAD_DEBUG_EVENT, thread );
372 release_object( thread );
375 /* suspend all the threads of a process */
376 void suspend_process( struct process *process )
378 if (!process->suspend++)
380 struct thread *thread = process->thread_list;
381 for (; thread; thread = thread->proc_next)
383 if (!thread->suspend) stop_thread( thread );
388 /* resume all the threads of a process */
389 void resume_process( struct process *process )
391 assert (process->suspend > 0);
392 if (!--process->suspend)
394 struct thread *thread = process->thread_list;
395 for (; thread; thread = thread->proc_next)
397 if (!thread->suspend) continue_thread( thread );
402 /* kill a process on the spot */
403 static void kill_process( struct process *process, struct thread *skip, int exit_code )
405 struct thread *thread = process->thread_list;
406 while (thread)
408 struct thread *next = thread->proc_next;
409 thread->exit_code = exit_code;
410 if (thread != skip) kill_thread( thread, 1 );
411 thread = next;
415 /* kill all processes being debugged by a given thread */
416 void kill_debugged_processes( struct thread *debugger, int exit_code )
418 for (;;) /* restart from the beginning of the list every time */
420 struct process *process = first_process;
421 /* find the first process being debugged by 'debugger' and still running */
422 while (process && (process->debugger != debugger || !process->running_threads))
423 process = process->next;
424 if (!process) return;
425 process->debugger = NULL;
426 kill_process( process, NULL, exit_code );
430 /* get all information about a process */
431 static void get_process_info( struct process *process, struct get_process_info_request *req )
433 req->pid = process;
434 req->debugged = (process->debugger != 0);
435 req->exit_code = process->exit_code;
436 req->priority = process->priority;
437 req->process_affinity = process->affinity;
438 req->system_affinity = 1;
441 /* set all information about a process */
442 static void set_process_info( struct process *process,
443 struct set_process_info_request *req )
445 if (req->mask & SET_PROCESS_INFO_PRIORITY)
446 process->priority = req->priority;
447 if (req->mask & SET_PROCESS_INFO_AFFINITY)
449 if (req->affinity != 1) set_error( STATUS_INVALID_PARAMETER );
450 else process->affinity = req->affinity;
454 /* read data from a process memory space */
455 /* len is the total size (in ints), max is the size we can actually store in the output buffer */
456 /* we read the total size in all cases to check for permissions */
457 static void read_process_memory( struct process *process, const int *addr,
458 size_t len, size_t max, int *dest )
460 struct thread *thread = process->thread_list;
462 if ((unsigned int)addr % sizeof(int)) /* address must be aligned */
464 set_error( STATUS_INVALID_PARAMETER );
465 return;
467 if (!thread) /* process is dead */
469 set_error( STATUS_ACCESS_DENIED );
470 return;
472 if (suspend_for_ptrace( thread ))
474 while (len > 0 && max)
476 if (read_thread_int( thread, addr++, dest++ ) == -1) goto done;
477 max--;
478 len--;
480 /* check the rest for read permission */
481 if (len > 0)
483 int dummy, page = get_page_size() / sizeof(int);
484 while (len >= page)
486 addr += page;
487 len -= page;
488 if (read_thread_int( thread, addr - 1, &dummy ) == -1) goto done;
490 if (len && (read_thread_int( thread, addr + len - 1, &dummy ) == -1)) goto done;
492 done:
493 resume_thread( thread );
497 /* write data to a process memory space */
498 /* len is the total size (in ints), max is the size we can actually read from the input buffer */
499 /* we check the total size for write permissions */
500 static void write_process_memory( struct process *process, int *addr, size_t len,
501 size_t max, unsigned int first_mask,
502 unsigned int last_mask, const int *src )
504 struct thread *thread = process->thread_list;
506 if (!len || ((unsigned int)addr % sizeof(int))) /* address must be aligned */
508 set_error( STATUS_INVALID_PARAMETER );
509 return;
511 if (!thread) /* process is dead */
513 set_error( STATUS_ACCESS_DENIED );
514 return;
516 if (suspend_for_ptrace( thread ))
518 /* first word is special */
519 if (len > 1)
521 if (write_thread_int( thread, addr++, *src++, first_mask ) == -1) goto done;
522 len--;
523 max--;
525 else last_mask &= first_mask;
527 while (len > 1 && max)
529 if (write_thread_int( thread, addr++, *src++, ~0 ) == -1) goto done;
530 max--;
531 len--;
534 if (max)
536 /* last word is special too */
537 if (write_thread_int( thread, addr, *src, last_mask ) == -1) goto done;
539 else
541 /* check the rest for write permission */
542 int page = get_page_size() / sizeof(int);
543 while (len >= page)
545 addr += page;
546 len -= page;
547 if (write_thread_int( thread, addr - 1, 0, 0 ) == -1) goto done;
549 if (len && (write_thread_int( thread, addr + len - 1, 0, 0 ) == -1)) goto done;
551 done:
552 resume_thread( thread );
556 /* take a snapshot of currently running processes */
557 struct process_snapshot *process_snap( int *count )
559 struct process_snapshot *snapshot, *ptr;
560 struct process *process;
561 if (!running_processes) return NULL;
562 if (!(snapshot = mem_alloc( sizeof(*snapshot) * running_processes )))
563 return NULL;
564 ptr = snapshot;
565 for (process = first_process; process; process = process->next)
567 if (!process->running_threads) continue;
568 ptr->process = process;
569 ptr->threads = process->running_threads;
570 ptr->priority = process->priority;
571 grab_object( process );
572 ptr++;
574 *count = running_processes;
575 return snapshot;
578 /* create a new process */
579 DECL_HANDLER(new_process)
581 size_t len = get_req_strlen( req, req->cmdline );
582 struct thread *thread;
583 int sock[2];
585 req->phandle = -1;
586 req->thandle = -1;
587 req->pid = NULL;
588 req->tid = NULL;
590 if (socketpair( AF_UNIX, SOCK_STREAM, 0, sock ) == -1)
592 file_set_error();
593 return;
596 if ((thread = create_process( sock[0], current->process, req, req->cmdline, len )))
598 int phandle = alloc_handle( current->process, thread->process,
599 PROCESS_ALL_ACCESS, req->pinherit );
600 if ((req->phandle = phandle) != -1)
602 if ((req->thandle = alloc_handle( current->process, thread,
603 THREAD_ALL_ACCESS, req->tinherit )) != -1)
605 /* thread object will be released when the thread gets killed */
606 set_reply_fd( current, sock[1] );
607 req->pid = thread->process;
608 req->tid = thread;
609 return;
611 close_handle( current->process, phandle );
613 release_object( thread );
615 close( sock[1] );
618 /* initialize a new process */
619 DECL_HANDLER(init_process)
621 struct new_process_request *info;
623 if (!current->unix_pid)
625 fatal_protocol_error( current, "init_process: init_thread not called yet\n" );
626 return;
628 if (!(info = current->process->info))
630 fatal_protocol_error( current, "init_process: called twice\n" );
631 return;
633 current->process->ldt_copy = req->ldt_copy;
634 current->process->ldt_flags = req->ldt_flags;
635 current->process->info = NULL;
636 req->exe_file = -1;
637 req->start_flags = info->start_flags;
638 req->hstdin = info->hstdin;
639 req->hstdout = info->hstdout;
640 req->hstderr = info->hstderr;
641 req->cmd_show = info->cmd_show;
642 req->env_ptr = info->env_ptr;
643 strcpy( req->cmdline, info->cmdline );
644 if (current->process->exe.file)
645 req->exe_file = alloc_handle( current->process, current->process->exe.file,
646 GENERIC_READ, 0 );
647 free( info );
650 /* signal the end of the process initialization */
651 DECL_HANDLER(init_process_done)
653 struct process *process = current->process;
654 if (!process->init_event)
656 fatal_protocol_error( current, "init_process_done: no event\n" );
657 return;
659 process->exe.base = req->module;
660 generate_startup_debug_events( current->process, req->entry );
661 set_event( process->init_event );
662 release_object( process->init_event );
663 process->init_event = NULL;
664 if (current->suspend + current->process->suspend > 0) stop_thread( current );
665 req->debugged = (current->process->debugger != 0);
668 /* open a handle to a process */
669 DECL_HANDLER(open_process)
671 struct process *process = get_process_from_id( req->pid );
672 req->handle = -1;
673 if (process)
675 req->handle = alloc_handle( current->process, process, req->access, req->inherit );
676 release_object( process );
680 /* terminate a process */
681 DECL_HANDLER(terminate_process)
683 struct process *process;
685 if ((process = get_process_from_handle( req->handle, PROCESS_TERMINATE )))
687 req->self = (current->process == process);
688 kill_process( process, current, req->exit_code );
689 release_object( process );
693 /* fetch information about a process */
694 DECL_HANDLER(get_process_info)
696 struct process *process;
698 if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
700 get_process_info( process, req );
701 release_object( process );
705 /* set information about a process */
706 DECL_HANDLER(set_process_info)
708 struct process *process;
710 if ((process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION )))
712 set_process_info( process, req );
713 release_object( process );
717 /* read data from a process address space */
718 DECL_HANDLER(read_process_memory)
720 struct process *process;
722 if ((process = get_process_from_handle( req->handle, PROCESS_VM_READ )))
724 read_process_memory( process, req->addr, req->len,
725 get_req_size( req, req->data, sizeof(int) ), req->data );
726 release_object( process );
730 /* write data to a process address space */
731 DECL_HANDLER(write_process_memory)
733 struct process *process;
735 if ((process = get_process_from_handle( req->handle, PROCESS_VM_WRITE )))
737 write_process_memory( process, req->addr, req->len,
738 get_req_size( req, req->data, sizeof(int) ),
739 req->first_mask, req->last_mask, req->data );
740 release_object( process );
744 /* notify the server that a dll has been loaded */
745 DECL_HANDLER(load_dll)
747 struct process_dll *dll;
748 struct file *file = NULL;
750 if ((req->handle != -1) &&
751 !(file = get_file_obj( current->process, req->handle, GENERIC_READ ))) return;
753 if ((dll = process_load_dll( current->process, file, req->base )))
755 dll->dbg_offset = req->dbg_offset;
756 dll->dbg_size = req->dbg_size;
757 dll->name = req->name;
758 /* only generate event if initialization is done */
759 if (!current->process->init_event)
760 generate_debug_event( current, LOAD_DLL_DEBUG_EVENT, dll );
762 if (file) release_object( file );
765 /* notify the server that a dll is being unloaded */
766 DECL_HANDLER(unload_dll)
768 process_unload_dll( current->process, req->base );