process.c 39.4 KB
Newer Older
Alexandre Julliard's avatar
Alexandre Julliard committed
1 2 3 4
/*
 * Server-side process management
 *
 * Copyright (C) 1998 Alexandre Julliard
5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Alexandre Julliard's avatar
Alexandre Julliard committed
19 20
 */

21
#include "config.h"
22
#include "wine/port.h"
23

Alexandre Julliard's avatar
Alexandre Julliard committed
24
#include <assert.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
25
#include <limits.h>
26
#include <signal.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
27
#include <string.h>
28
#include <stdarg.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
29
#include <stdio.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
30
#include <stdlib.h>
Alexandre Julliard's avatar
Alexandre Julliard committed
31
#include <sys/time.h>
32 33 34
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
Alexandre Julliard's avatar
Alexandre Julliard committed
35
#include <unistd.h>
36 37 38
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
Alexandre Julliard's avatar
Alexandre Julliard committed
39

40 41
#include "ntstatus.h"
#define WIN32_NO_STATUS
42
#include "winternl.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
43

44
#include "file.h"
45 46 47
#include "handle.h"
#include "process.h"
#include "thread.h"
48
#include "request.h"
49
#include "user.h"
50
#include "security.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
51

52
/* process structure */
53

54
static struct list process_list = LIST_INIT(process_list);
55
static int running_processes, user_processes;
56 57
static struct event *shutdown_event;           /* signaled when shutdown starts */
static struct timeout_user *shutdown_timeout;  /* timeout for server shutdown */
58
static int shutdown_stage;  /* current stage in the shutdown process */
Alexandre Julliard's avatar
Alexandre Julliard committed
59 60 61

/* process operations */

62
static void process_dump( struct object *obj, int verbose );
Alexandre Julliard's avatar
Alexandre Julliard committed
63
static int process_signaled( struct object *obj, struct thread *thread );
64
static unsigned int process_map_access( struct object *obj, unsigned int access );
65
static void process_poll_event( struct fd *fd, int event );
66
static void process_destroy( struct object *obj );
Alexandre Julliard's avatar
Alexandre Julliard committed
67 68 69

static const struct object_ops process_ops =
{
70 71
    sizeof(struct process),      /* size */
    process_dump,                /* dump */
72
    no_get_type,                 /* get_type */
73 74 75 76
    add_queue,                   /* add_queue */
    remove_queue,                /* remove_queue */
    process_signaled,            /* signaled */
    no_satisfied,                /* satisfied */
77
    no_signal,                   /* signal */
78
    no_get_fd,                   /* get_fd */
79
    process_map_access,          /* map_access */
80 81
    default_get_sd,              /* get_sd */
    default_set_sd,              /* set_sd */
82
    no_lookup_name,              /* lookup_name */
83
    no_open_file,                /* open_file */
84
    no_close_handle,             /* close_handle */
85 86 87 88 89
    process_destroy              /* destroy */
};

static const struct fd_ops process_fd_ops =
{
90
    NULL,                        /* get_poll_events */
91
    process_poll_event,          /* poll_event */
92 93
    NULL,                        /* flush */
    NULL,                        /* get_fd_type */
94
    NULL,                        /* ioctl */
95
    NULL,                        /* queue_async */
96
    NULL,                        /* reselect_async */
97
    NULL                         /* cancel async */
Alexandre Julliard's avatar
Alexandre Julliard committed
98 99
};

100 101 102
/* process startup info */

struct startup_info
103
{
104
    struct object       obj;          /* object header */
105 106 107
    obj_handle_t        hstdin;       /* handle for stdin */
    obj_handle_t        hstdout;      /* handle for stdout */
    obj_handle_t        hstderr;      /* handle for stderr */
108
    struct file        *exe_file;     /* file handle for main exe */
109
    struct process     *process;      /* created process */
110
    data_size_t         data_size;    /* size of startup data */
111
    void               *data;         /* data for startup info */
112
};
Alexandre Julliard's avatar
Alexandre Julliard committed
113

114 115 116 117 118
static void startup_info_dump( struct object *obj, int verbose );
static int startup_info_signaled( struct object *obj, struct thread *thread );
static void startup_info_destroy( struct object *obj );

static const struct object_ops startup_info_ops =
119
{
120 121
    sizeof(struct startup_info),   /* size */
    startup_info_dump,             /* dump */
122
    no_get_type,                   /* get_type */
123 124 125 126
    add_queue,                     /* add_queue */
    remove_queue,                  /* remove_queue */
    startup_info_signaled,         /* signaled */
    no_satisfied,                  /* satisfied */
127
    no_signal,                     /* signal */
128
    no_get_fd,                     /* get_fd */
129
    no_map_access,                 /* map_access */
130 131
    default_get_sd,                /* get_sd */
    default_set_sd,                /* set_sd */
132
    no_lookup_name,                /* lookup_name */
133
    no_open_file,                  /* open_file */
134
    no_close_handle,               /* close_handle */
135 136 137
    startup_info_destroy           /* destroy */
};

138

139 140 141 142 143 144 145 146 147 148 149 150
struct ptid_entry
{
    void        *ptr;   /* entry ptr */
    unsigned int next;  /* next free entry */
};

static struct ptid_entry *ptid_entries;     /* array of ptid entries */
static unsigned int used_ptid_entries;      /* number of entries in use */
static unsigned int alloc_ptid_entries;     /* number of allocated entries */
static unsigned int next_free_ptid;         /* next free entry */
static unsigned int last_free_ptid;         /* last free entry */

151 152
static void kill_all_processes(void);

153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
#define PTID_OFFSET 8  /* offset for first ptid value */

/* allocate a new process or thread id */
unsigned int alloc_ptid( void *ptr )
{
    struct ptid_entry *entry;
    unsigned int id;

    if (used_ptid_entries < alloc_ptid_entries)
    {
        id = used_ptid_entries + PTID_OFFSET;
        entry = &ptid_entries[used_ptid_entries++];
    }
    else if (next_free_ptid)
    {
        id = next_free_ptid;
        entry = &ptid_entries[id - PTID_OFFSET];
        if (!(next_free_ptid = entry->next)) last_free_ptid = 0;
    }
    else  /* need to grow the array */
    {
        unsigned int count = alloc_ptid_entries + (alloc_ptid_entries / 2);
        if (!count) count = 64;
        if (!(entry = realloc( ptid_entries, count * sizeof(*entry) )))
        {
            set_error( STATUS_NO_MEMORY );
            return 0;
        }
        ptid_entries = entry;
        alloc_ptid_entries = count;
        id = used_ptid_entries + PTID_OFFSET;
        entry = &ptid_entries[used_ptid_entries++];
    }

    entry->ptr = ptr;
    return id;
}

/* free a process or thread id */
void free_ptid( unsigned int id )
{
    struct ptid_entry *entry = &ptid_entries[id - PTID_OFFSET];

    entry->ptr  = NULL;
    entry->next = 0;

    /* append to end of free list so that we don't reuse it too early */
    if (last_free_ptid) ptid_entries[last_free_ptid - PTID_OFFSET].next = id;
    else next_free_ptid = id;

    last_free_ptid = id;
}

/* retrieve the pointer corresponding to a process or thread id */
void *get_ptid_entry( unsigned int id )
{
    if (id < PTID_OFFSET) return NULL;
    if (id - PTID_OFFSET >= used_ptid_entries) return NULL;
    return ptid_entries[id - PTID_OFFSET].ptr;
}

214 215 216 217 218 219 220 221
/* return the main thread of the process */
struct thread *get_process_first_thread( struct process *process )
{
    struct list *ptr = list_head( &process->thread_list );
    if (!ptr) return NULL;
    return LIST_ENTRY( ptr, struct thread, proc_entry );
}

222 223 224
/* set the state of the process startup info */
static void set_process_startup_state( struct process *process, enum startup_state state )
{
225 226 227 228 229 230 231
    if (process->startup_state == STARTUP_IN_PROGRESS) process->startup_state = state;
    if (process->startup_info)
    {
        wake_up( &process->startup_info->obj, 0 );
        release_object( process->startup_info );
        process->startup_info = NULL;
    }
232 233
}

234 235 236 237
/* callback for server shutdown */
static void server_shutdown_timeout( void *arg )
{
    shutdown_timeout = NULL;
238
    if (!running_processes)
239
    {
240 241 242 243 244 245
        close_master_socket( 0 );
        return;
    }
    switch(++shutdown_stage)
    {
    case 1:  /* signal system processes to exit */
246 247
        if (debug_level) fprintf( stderr, "wineserver: shutting down\n" );
        if (shutdown_event) set_event( shutdown_event );
248 249 250 251 252 253
        shutdown_timeout = add_timeout_user( 2 * -TICKS_PER_SEC, server_shutdown_timeout, NULL );
        close_master_socket( 4 * -TICKS_PER_SEC );
        break;
    case 2:  /* now forcibly kill all processes (but still wait for SIGKILL timeouts) */
        kill_all_processes();
        break;
254 255 256
    }
}

257 258 259 260 261 262 263 264 265 266 267 268 269
/* forced shutdown, used for wineserver -k */
void shutdown_master_socket(void)
{
    kill_all_processes();
    shutdown_stage = 2;
    if (shutdown_timeout)
    {
        remove_timeout_user( shutdown_timeout );
        shutdown_timeout = NULL;
    }
    close_master_socket( 2 * -TICKS_PER_SEC );  /* for SIGKILL timeouts */
}

270 271 272 273
/* final cleanup once we are sure a process is really dead */
static void process_died( struct process *process )
{
    if (debug_level) fprintf( stderr, "%04x: *process killed*\n", process->id );
274 275
    if (!process->is_system)
    {
276
        if (!--user_processes && !shutdown_stage && master_socket_timeout != TIMEOUT_INFINITE)
277
            shutdown_timeout = add_timeout_user( master_socket_timeout, server_shutdown_timeout, NULL );
278
    }
279
    release_object( process );
280
    if (!--running_processes && shutdown_stage) close_master_socket( 0 );
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
}

/* callback for process sigkill timeout */
static void process_sigkill( void *private )
{
    struct process *process = private;

    process->sigkill_timeout = NULL;
    kill( process->unix_pid, SIGKILL );
    process_died( process );
}

/* start the sigkill timer for a process upon exit */
static void start_sigkill_timer( struct process *process )
{
    grab_object( process );
    if (process->unix_pid != -1 && process->msg_fd)
298 299 300
        process->sigkill_timeout = add_timeout_user( -TICKS_PER_SEC, process_sigkill, process );
    else
        process_died( process );
301 302
}

303
/* create a new process and its main thread */
304 305
/* if the function fails the fd is closed */
struct thread *create_process( int fd, struct thread *parent_thread, int inherit_all )
306
{
307
    struct process *process;
308
    struct thread *thread = NULL;
309
    int request_pipe[2];
310

311 312 313 314 315
    if (!(process = alloc_object( &process_ops )))
    {
        close( fd );
        goto error;
    }
316
    process->parent          = NULL;
317
    process->debugger        = NULL;
318
    process->handles         = NULL;
319
    process->msg_fd          = NULL;
320 321
    process->sigkill_timeout = NULL;
    process->unix_pid        = -1;
322
    process->exit_code       = STILL_ACTIVE;
Alexandre Julliard's avatar
Alexandre Julliard committed
323
    process->running_threads = 0;
324
    process->priority        = PROCESS_PRIOCLASS_NORMAL;
325
    process->affinity        = ~0;
326
    process->suspend         = 0;
327
    process->is_system       = 0;
328
    process->create_flags    = 0;
329
    process->console         = NULL;
330
    process->startup_state   = STARTUP_IN_PROGRESS;
331
    process->startup_info    = NULL;
332 333
    process->idle_event      = NULL;
    process->queue           = NULL;
334
    process->peb             = NULL;
335
    process->ldt_copy        = NULL;
336
    process->winstation      = 0;
337
    process->desktop         = 0;
338
    process->token           = NULL;
339
    process->trace_data      = 0;
340
    list_init( &process->thread_list );
341
    list_init( &process->locks );
342
    list_init( &process->classes );
343
    list_init( &process->dlls );
344

345
    process->start_time = current_time;
346
    process->end_time = 0;
347
    list_add_tail( &process_list, &process->entry );
348

349 350 351 352 353
    if (!(process->id = process->group_id = alloc_ptid( process )))
    {
        close( fd );
        goto error;
    }
354
    if (!(process->msg_fd = create_anonymous_fd( &process_fd_ops, fd, &process->obj, 0 ))) goto error;
355

356
    /* create the handle table */
357 358 359 360 361
    if (!parent_thread)
    {
        process->handles = alloc_handle_table( process, 0 );
        process->token = token_create_admin();
    }
362 363 364 365 366 367
    else
    {
        struct process *parent = parent_thread->process;
        process->parent = (struct process *)grab_object( parent );
        process->handles = inherit_all ? copy_handle_table( process, parent )
                                       : alloc_handle_table( process, 0 );
368 369 370
        /* Note: for security reasons, starting a new process does not attempt
         * to use the current impersonation token for the new process */
        process->token = token_duplicate( parent->token, TRUE, 0 );
371
    }
372
    if (!process->handles || !process->token) goto error;
373

374
    /* create the main thread */
375 376 377 378 379
    if (pipe( request_pipe ) == -1)
    {
        file_set_error();
        goto error;
    }
380 381 382 383 384 385
    if (send_client_fd( process, request_pipe[1], 0 ) == -1)
    {
        close( request_pipe[0] );
        close( request_pipe[1] );
        goto error;
    }
386 387
    close( request_pipe[1] );
    if (!(thread = create_thread( request_pipe[0], process ))) goto error;
388

389
    set_fd_events( process->msg_fd, POLLIN );  /* start listening to events */
390 391 392 393
    release_object( process );
    return thread;

 error:
394 395
    if (process) release_object( process );
    /* if we failed to start our first process, close everything down */
396
    if (!running_processes) close_master_socket( 0 );
397 398 399 400
    return NULL;
}

/* initialize the current process and fill in the request */
401
data_size_t init_process( struct thread *thread )
402
{
403
    struct process *process = thread->process;
404
    struct startup_info *info = process->startup_info;
405

406
    init_process_tracing( process );
407 408
    if (!info) return 0;
    return info->data_size;
Alexandre Julliard's avatar
Alexandre Julliard committed
409 410 411
}

/* destroy a process when its refcount is 0 */
412
static void process_destroy( struct object *obj )
Alexandre Julliard's avatar
Alexandre Julliard committed
413 414 415 416
{
    struct process *process = (struct process *)obj;
    assert( obj->ops == &process_ops );

Alexandre Julliard's avatar
Alexandre Julliard committed
417
    /* we can't have a thread remaining */
418
    assert( list_empty( &process->thread_list ));
419

420 421
    assert( !process->sigkill_timeout );  /* timeout should hold a reference to the process */

422
    set_process_startup_state( process, STARTUP_ABORTED );
423 424
    if (process->console) release_object( process->console );
    if (process->parent) release_object( process->parent );
425
    if (process->msg_fd) release_object( process->msg_fd );
426
    list_remove( &process->entry );
427 428
    if (process->idle_event) release_object( process->idle_event );
    if (process->queue) release_object( process->queue );
429
    if (process->id) free_ptid( process->id );
430
    if (process->token) release_object( process->token );
Alexandre Julliard's avatar
Alexandre Julliard committed
431 432
}

Alexandre Julliard's avatar
Alexandre Julliard committed
433
/* dump a process on stdout for debugging purposes */
434
static void process_dump( struct object *obj, int verbose )
Alexandre Julliard's avatar
Alexandre Julliard committed
435 436 437 438
{
    struct process *process = (struct process *)obj;
    assert( obj->ops == &process_ops );

439
    fprintf( stderr, "Process id=%04x handles=%p\n", process->id, process->handles );
Alexandre Julliard's avatar
Alexandre Julliard committed
440 441
}

Alexandre Julliard's avatar
Alexandre Julliard committed
442 443 444
static int process_signaled( struct object *obj, struct thread *thread )
{
    struct process *process = (struct process *)obj;
445
    return !process->running_threads;
Alexandre Julliard's avatar
Alexandre Julliard committed
446 447
}

448 449 450 451 452 453 454 455 456
static unsigned int process_map_access( struct object *obj, unsigned int access )
{
    if (access & GENERIC_READ)    access |= STANDARD_RIGHTS_READ | SYNCHRONIZE;
    if (access & GENERIC_WRITE)   access |= STANDARD_RIGHTS_WRITE | SYNCHRONIZE;
    if (access & GENERIC_EXECUTE) access |= STANDARD_RIGHTS_EXECUTE;
    if (access & GENERIC_ALL)     access |= PROCESS_ALL_ACCESS;
    return access & ~(GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL);
}

457
static void process_poll_event( struct fd *fd, int event )
458
{
459 460
    struct process *process = get_fd_user( fd );
    assert( process->obj.ops == &process_ops );
461

462
    if (event & (POLLERR | POLLHUP)) kill_process( process, 0 );
463 464 465
    else if (event & POLLIN) receive_fd( process );
}

466 467 468 469
static void startup_info_destroy( struct object *obj )
{
    struct startup_info *info = (struct startup_info *)obj;
    assert( obj->ops == &startup_info_ops );
470
    free( info->data );
471
    if (info->exe_file) release_object( info->exe_file );
472 473 474 475 476 477 478 479
    if (info->process) release_object( info->process );
}

static void startup_info_dump( struct object *obj, int verbose )
{
    struct startup_info *info = (struct startup_info *)obj;
    assert( obj->ops == &startup_info_ops );

480 481
    fprintf( stderr, "Startup info in=%p out=%p err=%p\n",
             info->hstdin, info->hstdout, info->hstderr );
482 483 484 485 486
}

static int startup_info_signaled( struct object *obj, struct thread *thread )
{
    struct startup_info *info = (struct startup_info *)obj;
487
    return info->process && info->process->startup_state != STARTUP_IN_PROGRESS;
488 489
}

Alexandre Julliard's avatar
Alexandre Julliard committed
490
/* get a process from an id (and increment the refcount) */
491
struct process *get_process_from_id( process_id_t id )
Alexandre Julliard's avatar
Alexandre Julliard committed
492
{
493 494 495 496 497
    struct object *obj = get_ptid_entry( id );

    if (obj && obj->ops == &process_ops) return (struct process *)grab_object( obj );
    set_error( STATUS_INVALID_PARAMETER );
    return NULL;
Alexandre Julliard's avatar
Alexandre Julliard committed
498
}
Alexandre Julliard's avatar
Alexandre Julliard committed
499 500

/* get a process from a handle (and increment the refcount) */
501
struct process *get_process_from_handle( obj_handle_t handle, unsigned int access )
Alexandre Julliard's avatar
Alexandre Julliard committed
502 503 504 505 506
{
    return (struct process *)get_handle_obj( current->process, handle,
                                             access, &process_ops );
}

507 508 509 510 511 512 513 514 515 516 517 518
/* find a dll from its base address */
static inline struct process_dll *find_process_dll( struct process *process, void *base )
{
    struct process_dll *dll;

    LIST_FOR_EACH_ENTRY( dll, &process->dlls, struct process_dll, entry )
    {
        if (dll->base == base) return dll;
    }
    return NULL;
}

519 520
/* add a dll to a process list */
static struct process_dll *process_load_dll( struct process *process, struct file *file,
521
                                             void *base, const WCHAR *filename, data_size_t name_len )
522 523 524 525
{
    struct process_dll *dll;

    /* make sure we don't already have one with the same base address */
526
    if (find_process_dll( process, base ))
527 528 529 530 531 532 533 534 535
    {
        set_error( STATUS_INVALID_PARAMETER );
        return NULL;
    }

    if ((dll = mem_alloc( sizeof(*dll) )))
    {
        dll->file = NULL;
        dll->base = base;
536 537 538 539 540 541 542
        dll->filename = NULL;
        dll->namelen  = name_len;
        if (name_len && !(dll->filename = memdup( filename, name_len )))
        {
            free( dll );
            return NULL;
        }
543
        if (file) dll->file = grab_file_unless_removable( file );
544
        list_add_tail( &process->dlls, &dll->entry );
545 546 547 548 549 550 551
    }
    return dll;
}

/* remove a dll from a process list */
static void process_unload_dll( struct process *process, void *base )
{
552
    struct process_dll *dll = find_process_dll( process, base );
553

554
    if (dll && (&dll->entry != list_head( &process->dlls )))  /* main exe can't be unloaded */
555
    {
556
        if (dll->file) release_object( dll->file );
557
        free( dll->filename );
558 559 560
        list_remove( &dll->entry );
        free( dll );
        generate_debug_event( current, UNLOAD_DLL_DEBUG_EVENT, base );
561
    }
562
    else set_error( STATUS_INVALID_PARAMETER );
563 564
}

565 566 567
/* terminate a process with the given exit code */
static void terminate_process( struct process *process, struct thread *skip, int exit_code )
{
568 569
    struct list *ptr;

570
    if (skip && skip->process == process)  /* move it to the end of the list */
571 572 573 574 575
    {
        assert( skip->state != TERMINATED );
        list_remove( &skip->proc_entry );
        list_add_tail( &process->thread_list, &skip->proc_entry );
    }
576

577 578
    grab_object( process );  /* make sure it doesn't get freed when threads die */
    while ((ptr = list_head( &process->thread_list )))
579 580 581 582
    {
        struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );

        if (exit_code) thread->exit_code = exit_code;
583 584
        if (thread == skip) break;
        kill_thread( thread, 1 );
585
    }
586
    release_object( process );
587 588
}

589
/* kill all processes */
590
static void kill_all_processes(void)
591 592 593
{
    for (;;)
    {
594
        struct process *process;
595

596 597 598 599 600
        LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry )
        {
            if (process->running_threads) break;
        }
        if (&process->entry == &process_list) break;  /* no process found */
601
        terminate_process( process, NULL, 1 );
602 603 604
    }
}

605
/* kill all processes being attached to a console renderer */
606
void kill_console_processes( struct thread *renderer, int exit_code )
607 608 609
{
    for (;;)  /* restart from the beginning of the list every time */
    {
610
        struct process *process;
611 612

        /* find the first process being attached to 'renderer' and still running */
613
        LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry )
614
        {
615 616
            if (process == renderer->process) continue;
            if (!process->running_threads) continue;
617
            if (process->console && console_get_renderer( process->console ) == renderer) break;
618
        }
619
        if (&process->entry == &process_list) break;  /* no process found */
620
        terminate_process( process, NULL, exit_code );
621 622 623
    }
}

Alexandre Julliard's avatar
Alexandre Julliard committed
624
/* a process has been killed (i.e. its last thread died) */
625
static void process_killed( struct process *process )
Alexandre Julliard's avatar
Alexandre Julliard committed
626
{
627
    struct handle_table *handles;
628 629
    struct list *ptr;

630
    assert( list_empty( &process->thread_list ));
631
    process->end_time = current_time;
632
    if (!process->is_system) close_process_desktop( process );
633
    handles = process->handles;
634
    process->handles = NULL;
635
    if (handles) release_object( handles );
636 637

    /* close the console attached to this process, if any */
638
    free_console( process );
639

640
    while ((ptr = list_head( &process->dlls )))
641
    {
642
        struct process_dll *dll = LIST_ENTRY( ptr, struct process_dll, entry );
643
        if (dll->file) release_object( dll->file );
644
        free( dll->filename );
645
        list_remove( &dll->entry );
646 647
        free( dll );
    }
648
    destroy_process_classes( process );
649
    remove_process_locks( process );
650
    set_process_startup_state( process, STARTUP_ABORTED );
651
    finish_process_tracing( process );
652
    start_sigkill_timer( process );
Alexandre Julliard's avatar
Alexandre Julliard committed
653
    wake_up( &process->obj, 0 );
Alexandre Julliard's avatar
Alexandre Julliard committed
654 655 656 657 658
}

/* add a thread to a process running threads list */
void add_process_thread( struct process *process, struct thread *thread )
{
659
    list_add_tail( &process->thread_list, &thread->proc_entry );
660 661 662 663 664
    if (!process->running_threads++)
    {
        running_processes++;
        if (!process->is_system)
        {
665 666 667 668 669
            if (!user_processes++ && shutdown_timeout)
            {
                remove_timeout_user( shutdown_timeout );
                shutdown_timeout = NULL;
            }
670 671
        }
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
672 673 674 675 676 677 678
    grab_object( thread );
}

/* remove a thread from a process running threads list */
void remove_process_thread( struct process *process, struct thread *thread )
{
    assert( process->running_threads > 0 );
679
    assert( !list_empty( &process->thread_list ));
Alexandre Julliard's avatar
Alexandre Julliard committed
680

681
    list_remove( &thread->proc_entry );
Alexandre Julliard's avatar
Alexandre Julliard committed
682 683 684 685

    if (!--process->running_threads)
    {
        /* we have removed the last running thread, exit the process */
686 687 688
        process->exit_code = thread->exit_code;
        generate_debug_event( thread, EXIT_PROCESS_DEBUG_EVENT, process );
        process_killed( process );
Alexandre Julliard's avatar
Alexandre Julliard committed
689
    }
690
    else generate_debug_event( thread, EXIT_THREAD_DEBUG_EVENT, thread );
Alexandre Julliard's avatar
Alexandre Julliard committed
691 692 693
    release_object( thread );
}

694 695 696 697 698
/* suspend all the threads of a process */
void suspend_process( struct process *process )
{
    if (!process->suspend++)
    {
699 700 701
        struct list *ptr, *next;

        LIST_FOR_EACH_SAFE( ptr, next, &process->thread_list )
702
        {
703
            struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );
704
            if (!thread->suspend) stop_thread( thread );
705 706 707 708 709 710 711 712 713 714
        }
    }
}

/* resume all the threads of a process */
void resume_process( struct process *process )
{
    assert (process->suspend > 0);
    if (!--process->suspend)
    {
715 716 717
        struct list *ptr, *next;

        LIST_FOR_EACH_SAFE( ptr, next, &process->thread_list )
718
        {
719
            struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );
720
            if (!thread->suspend) wake_thread( thread );
721 722 723 724
        }
    }
}

Alexandre Julliard's avatar
Alexandre Julliard committed
725
/* kill a process on the spot */
726
void kill_process( struct process *process, int violent_death )
Alexandre Julliard's avatar
Alexandre Julliard committed
727
{
728 729 730 731 732 733 734 735 736 737 738 739 740 741
    if (!violent_death && process->msg_fd)  /* normal termination on pipe close */
    {
        release_object( process->msg_fd );
        process->msg_fd = NULL;
    }

    if (process->sigkill_timeout)  /* already waiting for it to die */
    {
        remove_timeout_user( process->sigkill_timeout );
        process->sigkill_timeout = NULL;
        process_died( process );
        return;
    }

742 743
    if (violent_death) terminate_process( process, NULL, 1 );
    else
744
    {
745
        struct list *ptr;
746

747 748
        grab_object( process );  /* make sure it doesn't get freed when threads die */
        while ((ptr = list_head( &process->thread_list )))
749 750 751 752
        {
            struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );
            kill_thread( thread, 0 );
        }
753
        release_object( process );
754
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
755 756
}

757 758 759 760 761
/* kill all processes being debugged by a given thread */
void kill_debugged_processes( struct thread *debugger, int exit_code )
{
    for (;;)  /* restart from the beginning of the list every time */
    {
762 763
        struct process *process;

764
        /* find the first process being debugged by 'debugger' and still running */
765 766 767 768 769 770
        LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry )
        {
            if (!process->running_threads) continue;
            if (process->debugger == debugger) break;
        }
        if (&process->entry == &process_list) break;  /* no process found */
771
        process->debugger = NULL;
772
        terminate_process( process, NULL, exit_code );
773 774 775
    }
}

776

777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798
/* trigger a breakpoint event in a given process */
void break_process( struct process *process )
{
    struct thread *thread;

    suspend_process( process );

    LIST_FOR_EACH_ENTRY( thread, &process->thread_list, struct thread, proc_entry )
    {
        if (thread->context)  /* inside an exception event already */
        {
            break_thread( thread );
            goto done;
        }
    }
    if ((thread = get_process_first_thread( process ))) thread->debug_break = 1;
    else set_error( STATUS_ACCESS_DENIED );
done:
    resume_process( process );
}


799 800 801 802
/* detach a debugger from all its debuggees */
void detach_debugged_processes( struct thread *debugger )
{
    struct process *process;
803 804

    LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry )
805 806 807 808 809 810 811 812 813
    {
        if (process->debugger == debugger && process->running_threads)
        {
            debugger_detach( process, debugger );
        }
    }
}


814 815
void enum_processes( int (*cb)(struct process*, void*), void *user )
{
816 817 818
    struct list *ptr, *next;

    LIST_FOR_EACH_SAFE( ptr, next, &process_list )
819
    {
820
        struct process *process = LIST_ENTRY( ptr, struct process, entry );
821 822 823 824
        if ((cb)(process, user)) break;
    }
}

825 826 827
/* set the debugged flag in the process PEB */
int set_process_debug_flag( struct process *process, int flag )
{
828
    char data = (flag != 0);
829 830

    /* BeingDebugged flag is the byte at offset 2 in the PEB */
831
    return write_process_memory( process, (char *)process->peb + 2, 1, &data );
832 833
}

834 835 836 837 838
/* take a snapshot of currently running processes */
struct process_snapshot *process_snap( int *count )
{
    struct process_snapshot *snapshot, *ptr;
    struct process *process;
839

840 841 842 843
    if (!running_processes) return NULL;
    if (!(snapshot = mem_alloc( sizeof(*snapshot) * running_processes )))
        return NULL;
    ptr = snapshot;
844
    LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry )
845 846 847 848
    {
        if (!process->running_threads) continue;
        ptr->process  = process;
        ptr->threads  = process->running_threads;
849
        ptr->count    = process->obj.refcount;
850
        ptr->priority = process->priority;
851
        ptr->handles  = get_handle_table_count(process);
852 853 854
        grab_object( process );
        ptr++;
    }
855 856 857 858 859 860

    if (!(*count = ptr - snapshot))
    {
        free( snapshot );
        snapshot = NULL;
    }
861 862
    return snapshot;
}
863

864 865 866 867 868
/* take a snapshot of the modules of a process */
struct module_snapshot *module_snap( struct process *process, int *count )
{
    struct module_snapshot *snapshot, *ptr;
    struct process_dll *dll;
869
    int total = 0;
870

871
    LIST_FOR_EACH_ENTRY( dll, &process->dlls, struct process_dll, entry ) total++;
872 873
    if (!(snapshot = mem_alloc( sizeof(*snapshot) * total ))) return NULL;

874
    ptr = snapshot;
875
    LIST_FOR_EACH_ENTRY( dll, &process->dlls, struct process_dll, entry )
876
    {
877 878 879 880
        ptr->base     = dll->base;
        ptr->size     = dll->size;
        ptr->namelen  = dll->namelen;
        ptr->filename = memdup( dll->filename, dll->namelen );
881
        ptr++;
882 883 884 885 886 887
    }
    *count = total;
    return snapshot;
}


888 889 890
/* create a new process */
DECL_HANDLER(new_process)
{
891
    struct startup_info *info;
892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907
    struct thread *thread;
    struct process *process;
    struct process *parent = current->process;
    int socket_fd = thread_get_inflight_fd( current, req->socket_fd );

    if (socket_fd == -1)
    {
        set_error( STATUS_INVALID_PARAMETER );
        return;
    }
    if (fcntl( socket_fd, F_SETFL, O_NONBLOCK ) == -1)
    {
        set_error( STATUS_INVALID_HANDLE );
        close( socket_fd );
        return;
    }
908
    if (shutdown_stage)
909 910 911 912 913
    {
        set_error( STATUS_SHUTDOWN_IN_PROGRESS );
        close( socket_fd );
        return;
    }
914

915
    /* build the startup info for a new process */
916
    if (!(info = alloc_object( &startup_info_ops ))) return;
917 918 919
    info->hstdin       = req->hstdin;
    info->hstdout      = req->hstdout;
    info->hstderr      = req->hstderr;
920
    info->exe_file     = NULL;
921
    info->process      = NULL;
922 923
    info->data_size    = get_req_data_size();
    info->data         = NULL;
924

925
    if (req->exe_file &&
926
        !(info->exe_file = get_file_obj( current->process, req->exe_file, FILE_READ_DATA )))
927 928
        goto done;

929
    if (!(info->data = memdup( get_req_data(), info->data_size ))) goto done;
930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974

    if (!(thread = create_process( socket_fd, current, req->inherit_all ))) goto done;
    process = thread->process;
    process->create_flags = req->create_flags;
    process->startup_info = (struct startup_info *)grab_object( info );

    /* connect to the window station */
    connect_process_winstation( process, current );

    /* thread will be actually suspended in init_done */
    if (req->create_flags & CREATE_SUSPENDED) thread->suspend++;

    /* set the process console */
    if (!(req->create_flags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)))
    {
        /* FIXME: some better error checking should be done...
         * like if hConOut and hConIn are console handles, then they should be on the same
         * physical console
         */
        inherit_console( current, process, req->inherit_all ? req->hstdin : 0 );
    }

    if (!req->inherit_all && !(req->create_flags & CREATE_NEW_CONSOLE))
    {
        info->hstdin  = duplicate_handle( parent, req->hstdin, process,
                                          0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
        info->hstdout = duplicate_handle( parent, req->hstdout, process,
                                          0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
        info->hstderr = duplicate_handle( parent, req->hstderr, process,
                                          0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
        /* some handles above may have been invalid; this is not an error */
        if (get_error() == STATUS_INVALID_HANDLE ||
            get_error() == STATUS_OBJECT_TYPE_MISMATCH) clear_error();
    }

    /* attach to the debugger if requested */
    if (req->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
        set_process_debugger( process, current );
    else if (parent->debugger && !(parent->create_flags & DEBUG_ONLY_THIS_PROCESS))
        set_process_debugger( process, parent->debugger );

    if (!(req->create_flags & CREATE_NEW_PROCESS_GROUP))
        process->group_id = parent->group_id;

    info->process = (struct process *)grab_object( process );
975
    reply->info = alloc_handle( current->process, info, SYNCHRONIZE, 0 );
976 977 978 979
    reply->pid = get_process_id( process );
    reply->tid = get_thread_id( thread );
    reply->phandle = alloc_handle( parent, process, req->process_access, req->process_attr );
    reply->thandle = alloc_handle( parent, thread, req->thread_access, req->thread_attr );
980 981 982

 done:
    release_object( info );
983
}
984

985 986
/* Retrieve information about a newly started process */
DECL_HANDLER(get_new_process_info)
987
{
988 989 990 991
    struct startup_info *info;

    if ((info = (struct startup_info *)get_handle_obj( current->process, req->info,
                                                       0, &startup_info_ops )))
992
    {
993
        reply->success = is_process_init_done( info->process );
994
        reply->exit_code = info->process->exit_code;
995
        release_object( info );
996
    }
997 998
}

999 1000 1001
/* Retrieve the new process startup info */
DECL_HANDLER(get_startup_info)
{
1002 1003
    struct process *process = current->process;
    struct startup_info *info = process->startup_info;
1004
    data_size_t size;
1005

1006 1007 1008 1009 1010
    if (!info) return;

    if (info->exe_file &&
        !(reply->exe_file = alloc_handle( process, info->exe_file, GENERIC_READ, 0 ))) return;

1011 1012 1013
    reply->hstdin  = info->hstdin;
    reply->hstdout = info->hstdout;
    reply->hstderr = info->hstderr;
1014 1015 1016 1017 1018 1019 1020

    /* we return the data directly without making a copy so this can only be called once */
    size = info->data_size;
    if (size > get_reply_max_size()) size = get_reply_max_size();
    set_reply_data_ptr( info->data, size );
    info->data = NULL;
    info->data_size = 0;
1021 1022
}

1023 1024 1025
/* signal the end of the process initialization */
DECL_HANDLER(init_process_done)
{
1026
    struct process_dll *dll;
1027
    struct process *process = current->process;
1028

1029
    if (is_process_init_done(process))
1030
    {
1031
        set_error( STATUS_INVALID_PARAMETER );
1032 1033
        return;
    }
1034
    if (!(dll = find_process_dll( process, req->module )))
1035
    {
1036 1037
        set_error( STATUS_DLL_NOT_FOUND );
        return;
1038
    }
1039

1040 1041 1042 1043
    /* main exe is the first in the dll list */
    list_remove( &dll->entry );
    list_add_head( &process->dlls, &dll->entry );

1044 1045 1046
    generate_startup_debug_events( process, req->entry );
    set_process_startup_state( process, STARTUP_DONE );

1047
    if (req->gui) process->idle_event = create_event( NULL, NULL, 0, 1, 0, NULL );
1048
    if (current->suspend + process->suspend > 0) stop_thread( current );
1049
    if (process->debugger) set_process_debug_flag( process, 1 );
1050 1051
}

1052 1053 1054 1055
/* open a handle to a process */
DECL_HANDLER(open_process)
{
    struct process *process = get_process_from_id( req->pid );
1056
    reply->handle = 0;
1057 1058
    if (process)
    {
1059
        reply->handle = alloc_handle( current->process, process, req->access, req->attributes );
1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070
        release_object( process );
    }
}

/* terminate a process */
DECL_HANDLER(terminate_process)
{
    struct process *process;

    if ((process = get_process_from_handle( req->handle, PROCESS_TERMINATE )))
    {
1071
        reply->self = (current->process == process);
1072
        terminate_process( process, current, req->exit_code );
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
        release_object( process );
    }
}

/* fetch information about a process */
DECL_HANDLER(get_process_info)
{
    struct process *process;

    if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
    {
1084
        reply->pid              = get_process_id( process );
1085
        reply->ppid             = process->parent ? get_process_id( process->parent ) : 0;
1086 1087
        reply->exit_code        = process->exit_code;
        reply->priority         = process->priority;
1088
        reply->affinity         = process->affinity;
1089
        reply->peb              = process->peb;
1090 1091
        reply->start_time       = process->start_time;
        reply->end_time         = process->end_time;
1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102
        release_object( process );
    }
}

/* set information about a process */
DECL_HANDLER(set_process_info)
{
    struct process *process;

    if ((process = get_process_from_handle( req->handle, PROCESS_SET_INFORMATION )))
    {
1103
        if (req->mask & SET_PROCESS_INFO_PRIORITY) process->priority = req->priority;
1104
        if (req->mask & SET_PROCESS_INFO_AFFINITY) process->affinity = req->affinity;
1105 1106 1107
        release_object( process );
    }
}
1108 1109 1110 1111 1112

/* read data from a process address space */
DECL_HANDLER(read_process_memory)
{
    struct process *process;
1113
    data_size_t len = get_reply_max_size();
1114

1115 1116 1117
    if (!(process = get_process_from_handle( req->handle, PROCESS_VM_READ ))) return;

    if (len)
1118
    {
1119
        char *buffer = mem_alloc( len );
1120 1121
        if (buffer)
        {
1122
            if (read_process_memory( process, req->addr, len, buffer ))
1123
                set_reply_data_ptr( buffer, len );
1124 1125
            else
                free( buffer );
1126
        }
1127
    }
1128
    release_object( process );
1129
}
1130 1131 1132 1133 1134 1135 1136 1137

/* write data to a process address space */
DECL_HANDLER(write_process_memory)
{
    struct process *process;

    if ((process = get_process_from_handle( req->handle, PROCESS_VM_WRITE )))
    {
1138
        data_size_t len = get_req_data_size();
1139 1140
        if (len) write_process_memory( process, req->addr, len, get_req_data() );
        else set_error( STATUS_INVALID_PARAMETER );
1141 1142 1143
        release_object( process );
    }
}
1144 1145 1146 1147 1148 1149 1150

/* notify the server that a dll has been loaded */
DECL_HANDLER(load_dll)
{
    struct process_dll *dll;
    struct file *file = NULL;

1151
    if (req->handle && !(file = get_file_obj( current->process, req->handle, FILE_READ_DATA )))
1152
        return;
1153

1154 1155
    if ((dll = process_load_dll( current->process, file, req->base,
                                 get_req_data(), get_req_data_size() )))
1156
    {
1157
        dll->size       = req->size;
1158 1159 1160 1161
        dll->dbg_offset = req->dbg_offset;
        dll->dbg_size   = req->dbg_size;
        dll->name       = req->name;
        /* only generate event if initialization is done */
1162
        if (is_process_init_done( current->process ))
1163 1164 1165 1166 1167 1168 1169 1170 1171 1172
            generate_debug_event( current, LOAD_DLL_DEBUG_EVENT, dll );
    }
    if (file) release_object( file );
}

/* notify the server that a dll is being unloaded */
DECL_HANDLER(unload_dll)
{
    process_unload_dll( current->process, req->base );
}
1173

1174 1175 1176 1177 1178 1179 1180
/* retrieve information about a module in a process */
DECL_HANDLER(get_dll_info)
{
    struct process *process;

    if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
    {
1181 1182 1183 1184 1185 1186 1187
        struct process_dll *dll;

        if (req->base_address)
            dll = find_process_dll( process, req->base_address );
        else /* NULL means main module */
            dll = list_head( &process->dlls ) ?
                LIST_ENTRY(list_head( &process->dlls ), struct process_dll, entry) : NULL;
1188

1189
        if (dll)
1190
        {
1191
            reply->size = dll->size;
1192
            reply->entry_point = NULL; /* FIXME */
1193
            reply->filename_len = dll->namelen;
1194
            if (dll->filename)
1195
            {
1196 1197 1198 1199
                if (dll->namelen <= get_reply_max_size())
                    set_reply_data( dll->filename, dll->namelen );
                else
                    set_error( STATUS_BUFFER_TOO_SMALL );
1200 1201
            }
        }
1202 1203 1204
        else
            set_error( STATUS_DLL_NOT_FOUND );

1205 1206 1207 1208
        release_object( process );
    }
}

1209 1210
/* retrieve the process idle event */
DECL_HANDLER(get_process_idle_event)
1211 1212 1213
{
    struct process *process;

1214
    reply->event = 0;
1215 1216
    if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
    {
1217
        if (process->idle_event && process != current->process)
1218 1219
            reply->event = alloc_handle( current->process, process->idle_event,
                                         EVENT_ALL_ACCESS, 0 );
1220 1221 1222
        release_object( process );
    }
}
1223 1224 1225 1226 1227 1228

/* make the current process a system process */
DECL_HANDLER(make_process_system)
{
    struct process *process = current->process;

1229
    if (!shutdown_event)
1230
    {
1231 1232
        if (!(shutdown_event = create_event( NULL, NULL, 0, 1, 0, NULL ))) return;
        make_object_static( (struct object *)shutdown_event );
1233 1234
    }

1235
    if (!(reply->event = alloc_handle( current->process, shutdown_event, SYNCHRONIZE, 0 )))
1236 1237 1238 1239 1240
        return;

    if (!process->is_system)
    {
        process->is_system = 1;
1241
        close_process_desktop( process );
1242
        if (!--user_processes && !shutdown_stage && master_socket_timeout != TIMEOUT_INFINITE)
1243
            shutdown_timeout = add_timeout_user( master_socket_timeout, server_shutdown_timeout, NULL );
1244 1245
    }
}