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 463 464 465 466 467 468 469 470 471
    if (event & (POLLERR | POLLHUP))
    {
        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 );
        }
472
        else kill_process( process, 0 );
473
    }
474 475 476
    else if (event & POLLIN) receive_fd( process );
}

477 478 479 480
static void startup_info_destroy( struct object *obj )
{
    struct startup_info *info = (struct startup_info *)obj;
    assert( obj->ops == &startup_info_ops );
481
    free( info->data );
482
    if (info->exe_file) release_object( info->exe_file );
483 484 485 486 487 488 489 490
    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 );

491 492
    fprintf( stderr, "Startup info in=%p out=%p err=%p\n",
             info->hstdin, info->hstdout, info->hstderr );
493 494 495 496 497
}

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

Alexandre Julliard's avatar
Alexandre Julliard committed
501
/* get a process from an id (and increment the refcount) */
502
struct process *get_process_from_id( process_id_t id )
Alexandre Julliard's avatar
Alexandre Julliard committed
503
{
504 505 506 507 508
    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
509
}
Alexandre Julliard's avatar
Alexandre Julliard committed
510 511

/* get a process from a handle (and increment the refcount) */
512
struct process *get_process_from_handle( obj_handle_t handle, unsigned int access )
Alexandre Julliard's avatar
Alexandre Julliard committed
513 514 515 516 517
{
    return (struct process *)get_handle_obj( current->process, handle,
                                             access, &process_ops );
}

518 519 520 521 522 523 524 525 526 527 528 529
/* 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;
}

530 531
/* add a dll to a process list */
static struct process_dll *process_load_dll( struct process *process, struct file *file,
532
                                             void *base, const WCHAR *filename, data_size_t name_len )
533 534 535 536
{
    struct process_dll *dll;

    /* make sure we don't already have one with the same base address */
537
    if (find_process_dll( process, base ))
538 539 540 541 542 543 544 545 546
    {
        set_error( STATUS_INVALID_PARAMETER );
        return NULL;
    }

    if ((dll = mem_alloc( sizeof(*dll) )))
    {
        dll->file = NULL;
        dll->base = base;
547 548 549 550 551 552 553
        dll->filename = NULL;
        dll->namelen  = name_len;
        if (name_len && !(dll->filename = memdup( filename, name_len )))
        {
            free( dll );
            return NULL;
        }
554
        if (file) dll->file = grab_file_unless_removable( file );
555
        list_add_tail( &process->dlls, &dll->entry );
556 557 558 559 560 561 562
    }
    return dll;
}

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

565
    if (dll && (&dll->entry != list_head( &process->dlls )))  /* main exe can't be unloaded */
566
    {
567
        if (dll->file) release_object( dll->file );
568
        free( dll->filename );
569 570 571
        list_remove( &dll->entry );
        free( dll );
        generate_debug_event( current, UNLOAD_DLL_DEBUG_EVENT, base );
572
    }
573
    else set_error( STATUS_INVALID_PARAMETER );
574 575
}

576 577 578
/* terminate a process with the given exit code */
static void terminate_process( struct process *process, struct thread *skip, int exit_code )
{
579 580
    struct list *ptr;

581
    if (skip && skip->process == process)  /* move it to the end of the list */
582 583 584 585 586
    {
        assert( skip->state != TERMINATED );
        list_remove( &skip->proc_entry );
        list_add_tail( &process->thread_list, &skip->proc_entry );
    }
587

588 589
    grab_object( process );  /* make sure it doesn't get freed when threads die */
    while ((ptr = list_head( &process->thread_list )))
590 591 592 593
    {
        struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );

        if (exit_code) thread->exit_code = exit_code;
594 595
        if (thread == skip) break;
        kill_thread( thread, 1 );
596
    }
597
    release_object( process );
598 599
}

600
/* kill all processes */
601
static void kill_all_processes(void)
602 603 604
{
    for (;;)
    {
605
        struct process *process;
606

607 608 609 610 611
        LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry )
        {
            if (process->running_threads) break;
        }
        if (&process->entry == &process_list) break;  /* no process found */
612
        terminate_process( process, NULL, 1 );
613 614 615
    }
}

616
/* kill all processes being attached to a console renderer */
617
void kill_console_processes( struct thread *renderer, int exit_code )
618 619 620
{
    for (;;)  /* restart from the beginning of the list every time */
    {
621
        struct process *process;
622 623

        /* find the first process being attached to 'renderer' and still running */
624
        LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry )
625
        {
626 627
            if (process == renderer->process) continue;
            if (!process->running_threads) continue;
628
            if (process->console && console_get_renderer( process->console ) == renderer) break;
629
        }
630
        if (&process->entry == &process_list) break;  /* no process found */
631
        terminate_process( process, NULL, exit_code );
632 633 634
    }
}

Alexandre Julliard's avatar
Alexandre Julliard committed
635
/* a process has been killed (i.e. its last thread died) */
636
static void process_killed( struct process *process )
Alexandre Julliard's avatar
Alexandre Julliard committed
637
{
638
    struct handle_table *handles;
639 640
    struct list *ptr;

641
    assert( list_empty( &process->thread_list ));
642
    process->end_time = current_time;
643
    if (!process->is_system) close_process_desktop( process );
644
    handles = process->handles;
645
    process->handles = NULL;
646
    if (handles) release_object( handles );
647 648

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

651
    while ((ptr = list_head( &process->dlls )))
652
    {
653
        struct process_dll *dll = LIST_ENTRY( ptr, struct process_dll, entry );
654
        if (dll->file) release_object( dll->file );
655
        free( dll->filename );
656
        list_remove( &dll->entry );
657 658
        free( dll );
    }
659
    destroy_process_classes( process );
660
    remove_process_locks( process );
661
    set_process_startup_state( process, STARTUP_ABORTED );
662
    finish_process_tracing( process );
663
    start_sigkill_timer( process );
Alexandre Julliard's avatar
Alexandre Julliard committed
664
    wake_up( &process->obj, 0 );
Alexandre Julliard's avatar
Alexandre Julliard committed
665 666 667 668 669
}

/* add a thread to a process running threads list */
void add_process_thread( struct process *process, struct thread *thread )
{
670
    list_add_tail( &process->thread_list, &thread->proc_entry );
671 672 673 674 675
    if (!process->running_threads++)
    {
        running_processes++;
        if (!process->is_system)
        {
676 677 678 679 680
            if (!user_processes++ && shutdown_timeout)
            {
                remove_timeout_user( shutdown_timeout );
                shutdown_timeout = NULL;
            }
681 682
        }
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
683 684 685 686 687 688 689
    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 );
690
    assert( !list_empty( &process->thread_list ));
Alexandre Julliard's avatar
Alexandre Julliard committed
691

692
    list_remove( &thread->proc_entry );
Alexandre Julliard's avatar
Alexandre Julliard committed
693 694 695 696

    if (!--process->running_threads)
    {
        /* we have removed the last running thread, exit the process */
697 698 699
        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
700
    }
701
    else generate_debug_event( thread, EXIT_THREAD_DEBUG_EVENT, thread );
Alexandre Julliard's avatar
Alexandre Julliard committed
702 703 704
    release_object( thread );
}

705 706 707 708 709
/* suspend all the threads of a process */
void suspend_process( struct process *process )
{
    if (!process->suspend++)
    {
710 711 712
        struct list *ptr, *next;

        LIST_FOR_EACH_SAFE( ptr, next, &process->thread_list )
713
        {
714
            struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );
715
            if (!thread->suspend) stop_thread( thread );
716 717 718 719 720 721 722 723 724 725
        }
    }
}

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

        LIST_FOR_EACH_SAFE( ptr, next, &process->thread_list )
729
        {
730
            struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );
731
            if (!thread->suspend) wake_thread( thread );
732 733 734 735
        }
    }
}

Alexandre Julliard's avatar
Alexandre Julliard committed
736
/* kill a process on the spot */
737
void kill_process( struct process *process, int violent_death )
Alexandre Julliard's avatar
Alexandre Julliard committed
738
{
739 740
    if (violent_death) terminate_process( process, NULL, 1 );
    else
741
    {
742
        struct list *ptr;
743

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

754 755 756 757 758
/* 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 */
    {
759 760
        struct process *process;

761
        /* find the first process being debugged by 'debugger' and still running */
762 763 764 765 766 767
        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 */
768
        process->debugger = NULL;
769
        terminate_process( process, NULL, exit_code );
770 771 772
    }
}

773

774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795
/* 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 );
}


796 797 798 799
/* detach a debugger from all its debuggees */
void detach_debugged_processes( struct thread *debugger )
{
    struct process *process;
800 801

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


811 812
void enum_processes( int (*cb)(struct process*, void*), void *user )
{
813 814 815
    struct list *ptr, *next;

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

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

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

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

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

    if (!(*count = ptr - snapshot))
    {
        free( snapshot );
        snapshot = NULL;
    }
858 859
    return snapshot;
}
860

861 862 863 864 865
/* 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;
866
    int total = 0;
867

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

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


885 886 887
/* create a new process */
DECL_HANDLER(new_process)
{
888
    struct startup_info *info;
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904
    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;
    }
905
    if (shutdown_stage)
906 907 908 909 910
    {
        set_error( STATUS_SHUTDOWN_IN_PROGRESS );
        close( socket_fd );
        return;
    }
911

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

922
    if (req->exe_file &&
923
        !(info->exe_file = get_file_obj( current->process, req->exe_file, FILE_READ_DATA )))
924 925
        goto done;

926
    if (!(info->data = memdup( get_req_data(), info->data_size ))) goto done;
927 928 929 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

    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 );
972
    reply->info = alloc_handle( current->process, info, SYNCHRONIZE, 0 );
973 974 975 976
    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 );
977 978 979

 done:
    release_object( info );
980
}
981

982 983
/* Retrieve information about a newly started process */
DECL_HANDLER(get_new_process_info)
984
{
985 986 987 988
    struct startup_info *info;

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

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

1003 1004 1005 1006 1007
    if (!info) return;

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

1008 1009 1010
    reply->hstdin  = info->hstdin;
    reply->hstdout = info->hstdout;
    reply->hstderr = info->hstderr;
1011 1012 1013 1014 1015 1016 1017

    /* 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;
1018 1019
}

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

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

1037 1038 1039 1040
    /* main exe is the first in the dll list */
    list_remove( &dll->entry );
    list_add_head( &process->dlls, &dll->entry );

1041 1042 1043
    generate_startup_debug_events( process, req->entry );
    set_process_startup_state( process, STARTUP_DONE );

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

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

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

    if ((process = get_process_from_handle( req->handle, PROCESS_TERMINATE )))
    {
1068
        reply->self = (current->process == process);
1069
        terminate_process( process, current, req->exit_code );
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
        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 )))
    {
1081
        reply->pid              = get_process_id( process );
1082
        reply->ppid             = process->parent ? get_process_id( process->parent ) : 0;
1083 1084
        reply->exit_code        = process->exit_code;
        reply->priority         = process->priority;
1085
        reply->affinity         = process->affinity;
1086
        reply->peb              = process->peb;
1087 1088
        reply->start_time       = process->start_time;
        reply->end_time         = process->end_time;
1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
        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 )))
    {
1100
        if (req->mask & SET_PROCESS_INFO_PRIORITY) process->priority = req->priority;
1101
        if (req->mask & SET_PROCESS_INFO_AFFINITY) process->affinity = req->affinity;
1102 1103 1104
        release_object( process );
    }
}
1105 1106 1107 1108 1109

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

1112 1113 1114
    if (!(process = get_process_from_handle( req->handle, PROCESS_VM_READ ))) return;

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

/* 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 )))
    {
1135
        data_size_t len = get_req_data_size();
1136 1137
        if (len) write_process_memory( process, req->addr, len, get_req_data() );
        else set_error( STATUS_INVALID_PARAMETER );
1138 1139 1140
        release_object( process );
    }
}
1141 1142 1143 1144 1145 1146 1147

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

1148
    if (req->handle && !(file = get_file_obj( current->process, req->handle, FILE_READ_DATA )))
1149
        return;
1150

1151 1152
    if ((dll = process_load_dll( current->process, file, req->base,
                                 get_req_data(), get_req_data_size() )))
1153
    {
1154
        dll->size       = req->size;
1155 1156 1157 1158
        dll->dbg_offset = req->dbg_offset;
        dll->dbg_size   = req->dbg_size;
        dll->name       = req->name;
        /* only generate event if initialization is done */
1159
        if (is_process_init_done( current->process ))
1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
            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 );
}
1170

1171 1172 1173 1174 1175 1176 1177
/* 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 )))
    {
1178 1179 1180 1181 1182 1183 1184
        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;
1185

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

1202 1203 1204 1205
        release_object( process );
    }
}

1206 1207
/* retrieve the process idle event */
DECL_HANDLER(get_process_idle_event)
1208 1209 1210
{
    struct process *process;

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

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

1226
    if (!shutdown_event)
1227
    {
1228 1229
        if (!(shutdown_event = create_event( NULL, NULL, 0, 1, 0, NULL ))) return;
        make_object_static( (struct object *)shutdown_event );
1230 1231
    }

1232
    if (!(reply->event = alloc_handle( current->process, shutdown_event, SYNCHRONIZE, 0 )))
1233 1234 1235 1236 1237
        return;

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