2 * Server-side process management
4 * Copyright (C) 1998 Alexandre Julliard
17 #ifdef HAVE_SYS_SOCKET_H
18 # include <sys/socket.h>
31 /* process structure */
33 static struct process
*first_process
;
34 static int running_processes
;
36 /* process operations */
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
);
43 static const struct object_ops process_ops
=
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 */
55 no_get_file_info
, /* get_file_info */
56 process_destroy
/* destroy */
59 /* process startup info */
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 */
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
);
82 static const struct object_ops startup_info_ops
=
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 */
94 no_get_file_info
, /* get_file_info */
95 startup_info_destroy
/* destroy */
99 /* set the console and stdio handles for a newly created process */
100 static int set_process_console( struct process
*process
, struct thread
*parent_thread
,
101 struct startup_info
*info
, struct init_process_reply
*reply
)
103 if (process
->create_flags
& CREATE_NEW_CONSOLE
)
105 /* let the process init do the allocation */
108 else if (parent_thread
&& !(process
->create_flags
& DETACHED_PROCESS
))
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
114 inherit_console( parent_thread
, process
,
115 (info
->inherit_all
|| (info
->start_flags
& STARTF_USESTDHANDLES
)) ?
120 if (!info
->inherit_all
&& !(info
->start_flags
& STARTF_USESTDHANDLES
))
122 /* duplicate the handle from the parent into this process */
123 reply
->hstdin
= duplicate_handle( parent_thread
->process
, info
->hstdin
, process
,
124 0, TRUE
, DUPLICATE_SAME_ACCESS
);
125 reply
->hstdout
= duplicate_handle( parent_thread
->process
, info
->hstdout
, process
,
126 0, TRUE
, DUPLICATE_SAME_ACCESS
);
127 reply
->hstderr
= duplicate_handle( parent_thread
->process
, info
->hstderr
, process
,
128 0, TRUE
, DUPLICATE_SAME_ACCESS
);
132 reply
->hstdin
= info
->hstdin
;
133 reply
->hstdout
= info
->hstdout
;
134 reply
->hstderr
= info
->hstderr
;
139 if (process
->console
)
141 reply
->hstdin
= alloc_handle( process
, process
->console
,
142 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
, 1 );
143 reply
->hstdout
= alloc_handle( process
, process
->console
->active
,
144 GENERIC_READ
| GENERIC_WRITE
, 1 );
145 reply
->hstderr
= alloc_handle( process
, process
->console
->active
,
146 GENERIC_READ
| GENERIC_WRITE
, 1 );
150 /* no parent, let the caller decide what to do */
151 reply
->hstdin
= reply
->hstdout
= reply
->hstderr
= 0;
154 /* some handles above may have been invalid; this is not an error */
155 if (get_error() == STATUS_INVALID_HANDLE
) clear_error();
159 /* create a new process and its main thread */
160 struct thread
*create_process( int fd
)
162 struct process
*process
;
163 struct thread
*thread
= NULL
;
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;
191 gettimeofday( &process
->start_time
, NULL
);
192 if ((process
->next
= first_process
) != NULL
) process
->next
->prev
= process
;
193 first_process
= process
;
195 /* create the init done event */
196 if (!(process
->init_event
= create_event( NULL
, 0, 1, 0 ))) goto error
;
198 /* create the main thread */
199 if (pipe( request_pipe
) == -1)
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
;
208 set_select_events( &process
->obj
, POLLIN
); /* start listening to events */
209 release_object( process
);
213 if (thread
) release_object( thread
);
214 release_object( process
);
218 /* initialize the current process and fill in the request */
219 static void init_process( int ppid
, struct init_process_reply
*reply
)
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
;
228 parent
= parent_thread
->process
;
229 info
= parent_thread
->info
;
232 fatal_protocol_error( current
, "init_process: parent but no info\n" );
237 fatal_protocol_error( current
, "init_process: called twice?\n" );
240 process
->parent
= (struct process
*)grab_object( parent
);
243 /* set the process flags */
244 process
->create_flags
= info
? info
->create_flags
: 0;
246 /* create the handle table */
247 if (parent
&& info
->inherit_all
)
248 process
->handles
= copy_handle_table( process
, parent
);
250 process
->handles
= alloc_handle_table( process
, 0 );
251 if (!process
->handles
) return;
253 /* retrieve the main exe file */
255 if (parent
&& info
->exe_file
)
257 process
->exe
.file
= (struct file
*)grab_object( info
->exe_file
);
258 if (!(reply
->exe_file
= alloc_handle( process
, process
->exe
.file
, GENERIC_READ
, 0 )))
262 /* set the process console */
263 if (!set_process_console( process
, parent_thread
, info
, reply
)) return;
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
);
274 /* thread will be actually suspended in init_done */
275 if (process
->create_flags
& CREATE_SUSPENDED
) current
->suspend
++;
279 size_t size
= strlen(info
->filename
);
280 if (size
> get_reply_max_size()) size
= get_reply_max_size();
281 reply
->start_flags
= info
->start_flags
;
282 reply
->cmd_show
= info
->cmd_show
;
283 set_reply_data( info
->filename
, size
);
284 info
->process
= (struct process
*)grab_object( process
);
285 info
->thread
= (struct thread
*)grab_object( current
);
286 wake_up( &info
->obj
, 0 );
290 reply
->start_flags
= STARTF_USESTDHANDLES
;
293 reply
->create_flags
= process
->create_flags
;
294 reply
->server_start
= server_start_ticks
;
297 /* destroy a process when its refcount is 0 */
298 static void process_destroy( struct object
*obj
)
300 struct process
*process
= (struct process
*)obj
;
301 assert( obj
->ops
== &process_ops
);
303 /* we can't have a thread remaining */
304 assert( !process
->thread_list
);
305 if (process
->console
) release_object( process
->console
);
306 if (process
->parent
) release_object( process
->parent
);
307 if (process
->next
) process
->next
->prev
= process
->prev
;
308 if (process
->prev
) process
->prev
->next
= process
->next
;
309 else first_process
= process
->next
;
310 if (process
->init_event
) release_object( process
->init_event
);
311 if (process
->idle_event
) release_object( process
->idle_event
);
312 if (process
->queue
) release_object( process
->queue
);
313 if (process
->atom_table
) release_object( process
->atom_table
);
314 if (process
->exe
.file
) release_object( process
->exe
.file
);
317 /* dump a process on stdout for debugging purposes */
318 static void process_dump( struct object
*obj
, int verbose
)
320 struct process
*process
= (struct process
*)obj
;
321 assert( obj
->ops
== &process_ops
);
323 fprintf( stderr
, "Process next=%p prev=%p handles=%p\n",
324 process
->next
, process
->prev
, process
->handles
);
327 static int process_signaled( struct object
*obj
, struct thread
*thread
)
329 struct process
*process
= (struct process
*)obj
;
330 return !process
->running_threads
;
334 static void process_poll_event( struct object
*obj
, int event
)
336 struct process
*process
= (struct process
*)obj
;
337 assert( obj
->ops
== &process_ops
);
339 if (event
& (POLLERR
| POLLHUP
)) set_select_events( obj
, -1 );
340 else if (event
& POLLIN
) receive_fd( process
);
343 static void startup_info_destroy( struct object
*obj
)
345 struct startup_info
*info
= (struct startup_info
*)obj
;
346 assert( obj
->ops
== &startup_info_ops
);
347 if (info
->filename
) free( info
->filename
);
348 if (info
->exe_file
) release_object( info
->exe_file
);
349 if (info
->process
) release_object( info
->process
);
350 if (info
->thread
) release_object( info
->thread
);
353 info
->owner
->info
= NULL
;
354 release_object( info
->owner
);
358 static void startup_info_dump( struct object
*obj
, int verbose
)
360 struct startup_info
*info
= (struct startup_info
*)obj
;
361 assert( obj
->ops
== &startup_info_ops
);
363 fprintf( stderr
, "Startup info flags=%x in=%d out=%d err=%d name='%s'\n",
364 info
->start_flags
, info
->hstdin
, info
->hstdout
, info
->hstderr
, info
->filename
);
367 static int startup_info_signaled( struct object
*obj
, struct thread
*thread
)
369 struct startup_info
*info
= (struct startup_info
*)obj
;
370 return (info
->thread
!= NULL
);
374 /* get a process from an id (and increment the refcount) */
375 struct process
*get_process_from_id( void *id
)
377 struct process
*p
= first_process
;
378 while (p
&& (p
!= id
)) p
= p
->next
;
379 if (p
) grab_object( p
);
380 else set_error( STATUS_INVALID_PARAMETER
);
384 /* get a process from a handle (and increment the refcount) */
385 struct process
*get_process_from_handle( handle_t handle
, unsigned int access
)
387 return (struct process
*)get_handle_obj( current
->process
, handle
,
388 access
, &process_ops
);
391 /* add a dll to a process list */
392 static struct process_dll
*process_load_dll( struct process
*process
, struct file
*file
,
395 struct process_dll
*dll
;
397 /* make sure we don't already have one with the same base address */
398 for (dll
= process
->exe
.next
; dll
; dll
= dll
->next
) if (dll
->base
== base
)
400 set_error( STATUS_INVALID_PARAMETER
);
404 if ((dll
= mem_alloc( sizeof(*dll
) )))
406 dll
->prev
= &process
->exe
;
409 if (file
) dll
->file
= (struct file
*)grab_object( file
);
410 if ((dll
->next
= process
->exe
.next
)) dll
->next
->prev
= dll
;
411 process
->exe
.next
= dll
;
416 /* remove a dll from a process list */
417 static void process_unload_dll( struct process
*process
, void *base
)
419 struct process_dll
*dll
;
421 for (dll
= process
->exe
.next
; dll
; dll
= dll
->next
)
423 if (dll
->base
== base
)
425 if (dll
->file
) release_object( dll
->file
);
426 if (dll
->next
) dll
->next
->prev
= dll
->prev
;
427 if (dll
->prev
) dll
->prev
->next
= dll
->next
;
429 generate_debug_event( current
, UNLOAD_DLL_DEBUG_EVENT
, base
);
433 set_error( STATUS_INVALID_PARAMETER
);
436 /* kill all processes being attached to a console renderer */
437 void kill_console_processes( struct thread
*renderer
, int exit_code
)
439 for (;;) /* restart from the beginning of the list every time */
441 struct process
*process
= first_process
;
443 /* find the first process being attached to 'renderer' and still running */
445 (process
== renderer
->process
|| !process
->console
||
446 process
->console
->renderer
!= renderer
|| !process
->running_threads
))
448 process
= process
->next
;
451 kill_process( process
, NULL
, exit_code
);
455 /* a process has been killed (i.e. its last thread died) */
456 static void process_killed( struct process
*process
)
458 assert( !process
->thread_list
);
459 gettimeofday( &process
->end_time
, NULL
);
460 if (process
->handles
) release_object( process
->handles
);
461 process
->handles
= NULL
;
463 /* close the console attached to this process, if any */
464 free_console( process
);
466 while (process
->exe
.next
)
468 struct process_dll
*dll
= process
->exe
.next
;
469 process
->exe
.next
= dll
->next
;
470 if (dll
->file
) release_object( dll
->file
);
473 if (process
->exe
.file
) release_object( process
->exe
.file
);
474 process
->exe
.file
= NULL
;
475 wake_up( &process
->obj
, 0 );
476 if (!--running_processes
)
478 /* last process died, close global handles */
479 close_global_handles();
480 /* this will cause the select loop to terminate */
481 if (!persistent_server
) close_master_socket();
485 /* add a thread to a process running threads list */
486 void add_process_thread( struct process
*process
, struct thread
*thread
)
488 thread
->proc_next
= process
->thread_list
;
489 thread
->proc_prev
= NULL
;
490 if (thread
->proc_next
) thread
->proc_next
->proc_prev
= thread
;
491 process
->thread_list
= thread
;
492 if (!process
->running_threads
++) running_processes
++;
493 grab_object( thread
);
496 /* remove a thread from a process running threads list */
497 void remove_process_thread( struct process
*process
, struct thread
*thread
)
499 assert( process
->running_threads
> 0 );
500 assert( process
->thread_list
);
502 if (thread
->proc_next
) thread
->proc_next
->proc_prev
= thread
->proc_prev
;
503 if (thread
->proc_prev
) thread
->proc_prev
->proc_next
= thread
->proc_next
;
504 else process
->thread_list
= thread
->proc_next
;
506 if (!--process
->running_threads
)
508 /* we have removed the last running thread, exit the process */
509 process
->exit_code
= thread
->exit_code
;
510 generate_debug_event( thread
, EXIT_PROCESS_DEBUG_EVENT
, process
);
511 process_killed( process
);
513 else generate_debug_event( thread
, EXIT_THREAD_DEBUG_EVENT
, thread
);
514 release_object( thread
);
517 /* suspend all the threads of a process */
518 void suspend_process( struct process
*process
)
520 if (!process
->suspend
++)
522 struct thread
*thread
= process
->thread_list
;
523 for (; thread
; thread
= thread
->proc_next
)
525 if (!thread
->suspend
) stop_thread( thread
);
530 /* resume all the threads of a process */
531 void resume_process( struct process
*process
)
533 assert (process
->suspend
> 0);
534 if (!--process
->suspend
)
536 struct thread
*thread
= process
->thread_list
;
537 for (; thread
; thread
= thread
->proc_next
)
539 if (!thread
->suspend
) continue_thread( thread
);
544 /* kill a process on the spot */
545 void kill_process( struct process
*process
, struct thread
*skip
, int exit_code
)
547 struct thread
*thread
= process
->thread_list
;
551 struct thread
*next
= thread
->proc_next
;
552 thread
->exit_code
= exit_code
;
553 if (thread
!= skip
) kill_thread( thread
, 1 );
558 /* kill all processes being debugged by a given thread */
559 void kill_debugged_processes( struct thread
*debugger
, int exit_code
)
561 for (;;) /* restart from the beginning of the list every time */
563 struct process
*process
= first_process
;
564 /* find the first process being debugged by 'debugger' and still running */
565 while (process
&& (process
->debugger
!= debugger
|| !process
->running_threads
))
566 process
= process
->next
;
567 if (!process
) return;
568 process
->debugger
= NULL
;
569 kill_process( process
, NULL
, exit_code
);
574 /* get all information about a process */
575 static void get_process_info( struct process
*process
, struct get_process_info_reply
*reply
)
577 reply
->pid
= process
;
578 reply
->debugged
= (process
->debugger
!= 0);
579 reply
->exit_code
= process
->exit_code
;
580 reply
->priority
= process
->priority
;
581 reply
->process_affinity
= process
->affinity
;
582 reply
->system_affinity
= 1;
585 /* set all information about a process */
586 static void set_process_info( struct process
*process
,
587 const struct set_process_info_request
*req
)
589 if (req
->mask
& SET_PROCESS_INFO_PRIORITY
)
590 process
->priority
= req
->priority
;
591 if (req
->mask
& SET_PROCESS_INFO_AFFINITY
)
593 if (req
->affinity
!= 1) set_error( STATUS_INVALID_PARAMETER
);
594 else process
->affinity
= req
->affinity
;
598 /* read data from a process memory space */
599 /* len is the total size (in ints) */
600 static int read_process_memory( struct process
*process
, const int *addr
, size_t len
, int *dest
)
602 struct thread
*thread
= process
->thread_list
;
604 assert( !((unsigned int)addr
% sizeof(int)) ); /* address must be aligned */
606 if (!thread
) /* process is dead */
608 set_error( STATUS_ACCESS_DENIED
);
611 if (suspend_for_ptrace( thread
))
615 if (read_thread_int( thread
, addr
++, dest
++ ) == -1) break;
618 resume_thread( thread
);
623 /* make sure we can write to the whole address range */
624 /* len is the total size (in ints) */
625 static int check_process_write_access( struct thread
*thread
, int *addr
, size_t len
)
627 int page
= get_page_size() / sizeof(int);
631 if (write_thread_int( thread
, addr
, 0, 0 ) == -1) return 0;
632 if (len
<= page
) break;
636 return (write_thread_int( thread
, addr
+ len
- 1, 0, 0 ) != -1);
639 /* write data to a process memory space */
640 /* len is the total size (in ints), max is the size we can actually read from the input buffer */
641 /* we check the total size for write permissions */
642 static void write_process_memory( struct process
*process
, int *addr
, size_t len
,
643 unsigned int first_mask
, unsigned int last_mask
, const int *src
)
645 struct thread
*thread
= process
->thread_list
;
647 assert( !((unsigned int)addr
% sizeof(int) )); /* address must be aligned */
649 if (!thread
) /* process is dead */
651 set_error( STATUS_ACCESS_DENIED
);
654 if (suspend_for_ptrace( thread
))
656 if (!check_process_write_access( thread
, addr
, len
))
658 set_error( STATUS_ACCESS_DENIED
);
661 /* first word is special */
664 if (write_thread_int( thread
, addr
++, *src
++, first_mask
) == -1) goto done
;
667 else last_mask
&= first_mask
;
671 if (write_thread_int( thread
, addr
++, *src
++, ~0 ) == -1) goto done
;
675 /* last word is special too */
676 if (write_thread_int( thread
, addr
, *src
, last_mask
) == -1) goto done
;
679 resume_thread( thread
);
683 /* take a snapshot of currently running processes */
684 struct process_snapshot
*process_snap( int *count
)
686 struct process_snapshot
*snapshot
, *ptr
;
687 struct process
*process
;
688 if (!running_processes
) return NULL
;
689 if (!(snapshot
= mem_alloc( sizeof(*snapshot
) * running_processes
)))
692 for (process
= first_process
; process
; process
= process
->next
)
694 if (!process
->running_threads
) continue;
695 ptr
->process
= process
;
696 ptr
->threads
= process
->running_threads
;
697 ptr
->count
= process
->obj
.refcount
;
698 ptr
->priority
= process
->priority
;
699 grab_object( process
);
702 *count
= running_processes
;
706 /* take a snapshot of the modules of a process */
707 struct module_snapshot
*module_snap( struct process
*process
, int *count
)
709 struct module_snapshot
*snapshot
, *ptr
;
710 struct process_dll
*dll
;
713 for (dll
= &process
->exe
; dll
; dll
= dll
->next
) total
++;
714 if (!(snapshot
= mem_alloc( sizeof(*snapshot
) * total
))) return NULL
;
716 for (ptr
= snapshot
, dll
= &process
->exe
; dll
; dll
= dll
->next
, ptr
++)
718 ptr
->base
= dll
->base
;
725 /* create a new process */
726 DECL_HANDLER(new_process
)
728 size_t len
= get_req_data_size();
729 struct startup_info
*info
;
733 fatal_protocol_error( current
, "new_process: another process is being created\n" );
737 /* build the startup info for a new process */
738 if (!(info
= alloc_object( &startup_info_ops
, -1 ))) return;
739 info
->inherit_all
= req
->inherit_all
;
740 info
->create_flags
= req
->create_flags
;
741 info
->start_flags
= req
->start_flags
;
742 info
->hstdin
= req
->hstdin
;
743 info
->hstdout
= req
->hstdout
;
744 info
->hstderr
= req
->hstderr
;
745 info
->cmd_show
= req
->cmd_show
;
746 info
->exe_file
= NULL
;
747 info
->filename
= NULL
;
748 info
->owner
= (struct thread
*)grab_object( current
);
749 info
->process
= NULL
;
753 !(info
->exe_file
= get_file_obj( current
->process
, req
->exe_file
, GENERIC_READ
)))
756 if (!(info
->filename
= mem_alloc( len
+ 1 ))) goto done
;
758 memcpy( info
->filename
, get_req_data(), len
);
759 info
->filename
[len
] = 0;
760 current
->info
= info
;
761 reply
->info
= alloc_handle( current
->process
, info
, SYNCHRONIZE
, FALSE
);
764 release_object( info
);
767 /* Retrieve information about a newly started process */
768 DECL_HANDLER(get_new_process_info
)
770 struct startup_info
*info
;
774 if ((info
= (struct startup_info
*)get_handle_obj( current
->process
, req
->info
,
775 0, &startup_info_ops
)))
777 reply
->pid
= get_process_id( info
->process
);
778 reply
->tid
= get_thread_id( info
->thread
);
779 reply
->phandle
= alloc_handle( current
->process
, info
->process
,
780 PROCESS_ALL_ACCESS
, req
->pinherit
);
781 reply
->thandle
= alloc_handle( current
->process
, info
->thread
,
782 THREAD_ALL_ACCESS
, req
->tinherit
);
783 if (info
->process
->init_event
)
784 reply
->event
= alloc_handle( current
->process
, info
->process
->init_event
,
785 EVENT_ALL_ACCESS
, 0 );
786 release_object( info
);
797 /* initialize a new process */
798 DECL_HANDLER(init_process
)
800 if (!current
->unix_pid
)
802 fatal_protocol_error( current
, "init_process: init_thread not called yet\n" );
805 current
->process
->ldt_copy
= req
->ldt_copy
;
806 init_process( req
->ppid
, reply
);
809 /* signal the end of the process initialization */
810 DECL_HANDLER(init_process_done
)
812 struct file
*file
= NULL
;
813 struct process
*process
= current
->process
;
815 if (!process
->init_event
)
817 fatal_protocol_error( current
, "init_process_done: no event\n" );
820 process
->exe
.base
= req
->module
;
821 process
->exe
.name
= req
->name
;
823 if (req
->exe_file
) file
= get_file_obj( current
->process
, req
->exe_file
, GENERIC_READ
);
824 if (process
->exe
.file
) release_object( process
->exe
.file
);
825 process
->exe
.file
= file
;
827 generate_startup_debug_events( current
->process
, req
->entry
);
828 set_event( process
->init_event
);
829 release_object( process
->init_event
);
830 process
->init_event
= NULL
;
831 if (req
->gui
) process
->idle_event
= create_event( NULL
, 0, 1, 0 );
832 if (current
->suspend
+ current
->process
->suspend
> 0) stop_thread( current
);
833 reply
->debugged
= (current
->process
->debugger
!= 0);
836 /* open a handle to a process */
837 DECL_HANDLER(open_process
)
839 struct process
*process
= get_process_from_id( req
->pid
);
843 reply
->handle
= alloc_handle( current
->process
, process
, req
->access
, req
->inherit
);
844 release_object( process
);
848 /* terminate a process */
849 DECL_HANDLER(terminate_process
)
851 struct process
*process
;
853 if ((process
= get_process_from_handle( req
->handle
, PROCESS_TERMINATE
)))
855 reply
->self
= (current
->process
== process
);
856 kill_process( process
, current
, req
->exit_code
);
857 release_object( process
);
861 /* fetch information about a process */
862 DECL_HANDLER(get_process_info
)
864 struct process
*process
;
866 if ((process
= get_process_from_handle( req
->handle
, PROCESS_QUERY_INFORMATION
)))
868 get_process_info( process
, reply
);
869 release_object( process
);
873 /* set information about a process */
874 DECL_HANDLER(set_process_info
)
876 struct process
*process
;
878 if ((process
= get_process_from_handle( req
->handle
, PROCESS_SET_INFORMATION
)))
880 set_process_info( process
, req
);
881 release_object( process
);
885 /* read data from a process address space */
886 DECL_HANDLER(read_process_memory
)
888 struct process
*process
;
889 size_t len
= get_reply_max_size();
891 if (!(process
= get_process_from_handle( req
->handle
, PROCESS_VM_READ
))) return;
895 unsigned int start_offset
= (unsigned int)req
->addr
% sizeof(int);
896 unsigned int nb_ints
= (len
+ start_offset
+ sizeof(int) - 1) / sizeof(int);
897 const int *start
= (int *)((char *)req
->addr
- start_offset
);
898 int *buffer
= mem_alloc( nb_ints
* sizeof(int) );
901 if (read_process_memory( process
, start
, nb_ints
, buffer
))
903 /* move start of requested data to start of buffer */
904 if (start_offset
) memmove( buffer
, (char *)buffer
+ start_offset
, len
);
905 set_reply_data_ptr( buffer
, len
);
910 release_object( process
);
913 /* write data to a process address space */
914 DECL_HANDLER(write_process_memory
)
916 struct process
*process
;
918 if ((process
= get_process_from_handle( req
->handle
, PROCESS_VM_WRITE
)))
920 size_t len
= get_req_data_size();
921 if ((len
% sizeof(int)) || ((unsigned int)req
->addr
% sizeof(int)))
922 set_error( STATUS_INVALID_PARAMETER
);
925 if (len
) write_process_memory( process
, req
->addr
, len
/ sizeof(int),
926 req
->first_mask
, req
->last_mask
, get_req_data() );
928 release_object( process
);
932 /* notify the server that a dll has been loaded */
933 DECL_HANDLER(load_dll
)
935 struct process_dll
*dll
;
936 struct file
*file
= NULL
;
939 !(file
= get_file_obj( current
->process
, req
->handle
, GENERIC_READ
))) return;
941 if ((dll
= process_load_dll( current
->process
, file
, req
->base
)))
943 dll
->dbg_offset
= req
->dbg_offset
;
944 dll
->dbg_size
= req
->dbg_size
;
945 dll
->name
= req
->name
;
946 /* only generate event if initialization is done */
947 if (!current
->process
->init_event
)
948 generate_debug_event( current
, LOAD_DLL_DEBUG_EVENT
, dll
);
950 if (file
) release_object( file
);
953 /* notify the server that a dll is being unloaded */
954 DECL_HANDLER(unload_dll
)
956 process_unload_dll( current
->process
, req
->base
);
959 /* wait for a process to start waiting on input */
960 /* FIXME: only returns event for now, wait is done in the client */
961 DECL_HANDLER(wait_input_idle
)
963 struct process
*process
;
966 if ((process
= get_process_from_handle( req
->handle
, PROCESS_QUERY_INFORMATION
)))
968 if (process
->idle_event
&& process
!= current
->process
&& process
->queue
!= current
->queue
)
969 reply
->event
= alloc_handle( current
->process
, process
->idle_event
,
970 EVENT_ALL_ACCESS
, 0 );
971 release_object( process
);