process.c 38.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 18
 *
 * 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
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "console.h"
50
#include "user.h"
51
#include "security.h"
Alexandre Julliard's avatar
Alexandre Julliard committed
52

53
/* process structure */
54

55
static struct list process_list = LIST_INIT(process_list);
56
static int running_processes;
Alexandre Julliard's avatar
Alexandre Julliard committed
57 58 59

/* process operations */

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

static const struct object_ops process_ops =
{
68 69 70 71 72 73
    sizeof(struct process),      /* size */
    process_dump,                /* dump */
    add_queue,                   /* add_queue */
    remove_queue,                /* remove_queue */
    process_signaled,            /* signaled */
    no_satisfied,                /* satisfied */
74
    no_signal,                   /* signal */
75
    no_get_fd,                   /* get_fd */
76
    process_map_access,          /* map_access */
77
    no_lookup_name,              /* lookup_name */
78
    no_close_handle,             /* close_handle */
79 80 81 82 83
    process_destroy              /* destroy */
};

static const struct fd_ops process_fd_ops =
{
84
    NULL,                        /* get_poll_events */
85
    process_poll_event,          /* poll_event */
86 87
    no_flush,                    /* flush */
    no_get_file_info,            /* get_file_info */
88 89
    no_queue_async,              /* queue_async */
    no_cancel_async              /* cancel async */
Alexandre Julliard's avatar
Alexandre Julliard committed
90 91
};

92 93 94
/* process startup info */

struct startup_info
95
{
96
    struct object       obj;          /* object header */
97
    struct list         entry;        /* entry in list of startup infos */
98
    int                 inherit_all;  /* inherit all handles from parent */
99
    unsigned int        create_flags; /* creation flags */
100
    int                 unix_pid;     /* Unix pid of new process */
101 102 103
    obj_handle_t        hstdin;       /* handle for stdin */
    obj_handle_t        hstdout;      /* handle for stdout */
    obj_handle_t        hstderr;      /* handle for stderr */
104
    struct file        *exe_file;     /* file handle for main exe */
105
    struct thread      *owner;        /* owner thread (the one that created the new process) */
106 107
    struct process     *process;      /* created process */
    struct thread      *thread;       /* created thread */
108
    size_t              data_size;    /* size of startup data */
109
    void               *data;         /* data for startup info */
110
};
Alexandre Julliard's avatar
Alexandre Julliard committed
111

112 113 114 115 116
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 =
117
{
118 119 120 121 122 123
    sizeof(struct startup_info),   /* size */
    startup_info_dump,             /* dump */
    add_queue,                     /* add_queue */
    remove_queue,                  /* remove_queue */
    startup_info_signaled,         /* signaled */
    no_satisfied,                  /* satisfied */
124
    no_signal,                     /* signal */
125
    no_get_fd,                     /* get_fd */
126
    no_map_access,                 /* map_access */
127
    no_lookup_name,                /* lookup_name */
128
    no_close_handle,               /* close_handle */
129 130 131
    startup_info_destroy           /* destroy */
};

132

133 134
static struct list startup_info_list = LIST_INIT(startup_info_list);

135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 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
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 */

#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;
}

208 209 210 211 212 213 214 215
/* 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 );
}

216 217 218
/* set the state of the process startup info */
static void set_process_startup_state( struct process *process, enum startup_state state )
{
219 220 221 222 223 224 225
    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;
    }
226 227
}

228
/* create a new process and its main thread */
229
struct thread *create_process( int fd )
230
{
231
    struct process *process;
232
    struct thread *thread = NULL;
233
    int request_pipe[2];
234

235
    if (!(process = alloc_object( &process_ops ))) goto error;
236
    process->parent          = NULL;
237
    process->debugger        = NULL;
238
    process->handles         = NULL;
239
    process->msg_fd          = NULL;
240
    process->exit_code       = STILL_ACTIVE;
Alexandre Julliard's avatar
Alexandre Julliard committed
241
    process->running_threads = 0;
242
    process->priority        = PROCESS_PRIOCLASS_NORMAL;
243
    process->affinity        = 1;
244
    process->suspend         = 0;
245
    process->create_flags    = 0;
246
    process->console         = NULL;
247
    process->startup_state   = STARTUP_IN_PROGRESS;
248
    process->startup_info    = NULL;
249 250
    process->idle_event      = NULL;
    process->queue           = NULL;
251
    process->peb             = NULL;
252
    process->ldt_copy        = NULL;
253
    process->winstation      = 0;
254
    process->desktop         = 0;
255 256 257
    process->exe.file        = NULL;
    process->exe.dbg_offset  = 0;
    process->exe.dbg_size    = 0;
258 259
    process->exe.namelen     = 0;
    process->exe.filename    = NULL;
260
    process->token           = token_create_admin();
261
    list_init( &process->thread_list );
262
    list_init( &process->locks );
263
    list_init( &process->classes );
264
    list_init( &process->dlls );
265

266
    gettimeofday( &process->start_time, NULL );
267
    list_add_head( &process_list, &process->entry );
268

269
    if (!(process->id = process->group_id = alloc_ptid( process ))) goto error;
270
    if (!(process->msg_fd = create_anonymous_fd( &process_fd_ops, fd, &process->obj ))) goto error;
271

272
    /* create the main thread */
273 274 275 276 277
    if (pipe( request_pipe ) == -1)
    {
        file_set_error();
        goto error;
    }
278 279 280 281 282 283
    if (send_client_fd( process, request_pipe[1], 0 ) == -1)
    {
        close( request_pipe[0] );
        close( request_pipe[1] );
        goto error;
    }
284 285
    close( request_pipe[1] );
    if (!(thread = create_thread( request_pipe[0], process ))) goto error;
286

287
    set_fd_events( process->msg_fd, POLLIN );  /* start listening to events */
288 289 290 291
    release_object( process );
    return thread;

 error:
292 293 294
    if (process) release_object( process );
    /* if we failed to start our first process, close everything down */
    if (!running_processes) close_master_socket();
295 296 297
    return NULL;
}

298
/* find the startup info for a given Unix process */
299
inline static struct startup_info *find_startup_info( int unix_pid )
300 301 302 303 304 305 306 307 308 309 310
{
    struct list *ptr;

    LIST_FOR_EACH( ptr, &startup_info_list )
    {
        struct startup_info *info = LIST_ENTRY( ptr, struct startup_info, entry );
        if (info->unix_pid == unix_pid) return info;
    }
    return NULL;
}

311
/* initialize the current process and fill in the request */
312
size_t init_process( struct thread *thread )
313
{
314
    struct process *process = thread->process;
315
    struct thread *parent_thread = NULL;
316
    struct process *parent = NULL;
317 318
    struct startup_info *info;

319
    if (process->startup_info) return process->startup_info->data_size;  /* already initialized */
320

321
    if ((info = find_startup_info( thread->unix_pid )))
322
    {
323
        if (info->thread) return info->data_size;  /* already initialized */
324 325 326 327 328

        info->thread  = (struct thread *)grab_object( thread );
        info->process = (struct process *)grab_object( process );
        process->startup_info = (struct startup_info *)grab_object( info );

329 330
        parent_thread = info->owner;
        parent = parent_thread->process;
331
        process->parent = (struct process *)grab_object( parent );
332

333 334
        /* set the process flags */
        process->create_flags = info->create_flags;
335

336 337
        if (info->inherit_all) process->handles = copy_handle_table( process, parent );
    }
338

339 340 341 342 343
    /* create the handle table */
    if (!process->handles) process->handles = alloc_handle_table( process, 0 );
    if (!process->handles)
    {
        fatal_protocol_error( thread, "Failed to allocate handle table\n" );
344
        return 0;
345
    }
346

347
    /* connect to the window station and desktop */
348 349
    connect_process_winstation( process, NULL );
    connect_process_desktop( process, NULL );
350 351
    thread->desktop = process->desktop;

352
    if (!info) return 0;
353 354 355 356 357 358

    /* retrieve the main exe file */
    if (info->exe_file) process->exe.file = (struct file *)grab_object( info->exe_file );

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

360
    /* set the process console */
361
    if (!(info->create_flags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)))
362 363 364 365 366 367 368
    {
        /* 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( parent_thread, process, info->inherit_all ? info->hstdin : 0 );
    }
369

370 371 372 373 374
    /* attach to the debugger if requested */
    if (process->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
        set_process_debugger( process, parent_thread );
    else if (parent->debugger && !(parent->create_flags & DEBUG_ONLY_THIS_PROCESS))
        set_process_debugger( process, parent->debugger );
375

376 377
    if (!(process->create_flags & CREATE_NEW_PROCESS_GROUP))
        process->group_id = parent->group_id;
378 379

    return info->data_size;
Alexandre Julliard's avatar
Alexandre Julliard committed
380 381 382
}

/* destroy a process when its refcount is 0 */
383
static void process_destroy( struct object *obj )
Alexandre Julliard's avatar
Alexandre Julliard committed
384 385 386 387
{
    struct process *process = (struct process *)obj;
    assert( obj->ops == &process_ops );

Alexandre Julliard's avatar
Alexandre Julliard committed
388
    /* we can't have a thread remaining */
389
    assert( list_empty( &process->thread_list ));
390 391

    set_process_startup_state( process, STARTUP_ABORTED );
392 393
    if (process->console) release_object( process->console );
    if (process->parent) release_object( process->parent );
394
    if (process->msg_fd) release_object( process->msg_fd );
395
    list_remove( &process->entry );
396 397
    if (process->idle_event) release_object( process->idle_event );
    if (process->queue) release_object( process->queue );
398
    if (process->exe.file) release_object( process->exe.file );
399
    if (process->exe.filename) free( process->exe.filename );
400
    if (process->id) free_ptid( process->id );
401
    if (process->token) release_object( process->token );
Alexandre Julliard's avatar
Alexandre Julliard committed
402 403
}

Alexandre Julliard's avatar
Alexandre Julliard committed
404
/* dump a process on stdout for debugging purposes */
405
static void process_dump( struct object *obj, int verbose )
Alexandre Julliard's avatar
Alexandre Julliard committed
406 407 408 409
{
    struct process *process = (struct process *)obj;
    assert( obj->ops == &process_ops );

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

Alexandre Julliard's avatar
Alexandre Julliard committed
413 414 415
static int process_signaled( struct object *obj, struct thread *thread )
{
    struct process *process = (struct process *)obj;
416
    return !process->running_threads;
Alexandre Julliard's avatar
Alexandre Julliard committed
417 418
}

419 420 421 422 423 424 425 426 427
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);
}

428
static void process_poll_event( struct fd *fd, int event )
429
{
430 431
    struct process *process = get_fd_user( fd );
    assert( process->obj.ops == &process_ops );
432

433
    if (event & (POLLERR | POLLHUP)) set_fd_events( fd, -1 );
434 435 436
    else if (event & POLLIN) receive_fd( process );
}

437 438 439 440
static void startup_info_destroy( struct object *obj )
{
    struct startup_info *info = (struct startup_info *)obj;
    assert( obj->ops == &startup_info_ops );
441
    list_remove( &info->entry );
442
    if (info->data) free( info->data );
443
    if (info->exe_file) release_object( info->exe_file );
444 445
    if (info->process) release_object( info->process );
    if (info->thread) release_object( info->thread );
446
    if (info->owner) release_object( info->owner );
447 448 449 450 451 452 453
}

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

454
    fprintf( stderr, "Startup info flags=%x in=%p out=%p err=%p\n",
455
             info->create_flags, info->hstdin, info->hstdout, info->hstderr );
456 457 458 459 460
}

static int startup_info_signaled( struct object *obj, struct thread *thread )
{
    struct startup_info *info = (struct startup_info *)obj;
461
    return info->process && is_process_init_done(info->process);
462 463
}

Alexandre Julliard's avatar
Alexandre Julliard committed
464
/* get a process from an id (and increment the refcount) */
465
struct process *get_process_from_id( process_id_t id )
Alexandre Julliard's avatar
Alexandre Julliard committed
466
{
467 468 469 470 471
    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
472
}
Alexandre Julliard's avatar
Alexandre Julliard committed
473 474

/* get a process from a handle (and increment the refcount) */
475
struct process *get_process_from_handle( obj_handle_t handle, unsigned int access )
Alexandre Julliard's avatar
Alexandre Julliard committed
476 477 478 479 480
{
    return (struct process *)get_handle_obj( current->process, handle,
                                             access, &process_ops );
}

481 482 483 484 485 486 487 488 489 490 491 492 493 494
/* find a dll from its base address */
static inline struct process_dll *find_process_dll( struct process *process, void *base )
{
    struct process_dll *dll;

    if (process->exe.base == base) return &process->exe;

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

495 496
/* add a dll to a process list */
static struct process_dll *process_load_dll( struct process *process, struct file *file,
497
                                             void *base, const WCHAR *filename, size_t name_len )
498 499 500 501
{
    struct process_dll *dll;

    /* make sure we don't already have one with the same base address */
502
    if (find_process_dll( process, base ))
503 504 505 506 507 508 509 510 511
    {
        set_error( STATUS_INVALID_PARAMETER );
        return NULL;
    }

    if ((dll = mem_alloc( sizeof(*dll) )))
    {
        dll->file = NULL;
        dll->base = base;
512 513 514 515 516 517 518
        dll->filename = NULL;
        dll->namelen  = name_len;
        if (name_len && !(dll->filename = memdup( filename, name_len )))
        {
            free( dll );
            return NULL;
        }
519
        if (file) dll->file = (struct file *)grab_object( file );
520
        list_add_head( &process->dlls, &dll->entry );
521 522 523 524 525 526 527
    }
    return dll;
}

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

530
    if (dll && dll != &process->exe)
531
    {
532 533 534 535 536
        if (dll->file) release_object( dll->file );
        if (dll->filename) free( dll->filename );
        list_remove( &dll->entry );
        free( dll );
        generate_debug_event( current, UNLOAD_DLL_DEBUG_EVENT, base );
537
    }
538
    else set_error( STATUS_INVALID_PARAMETER );
539 540
}

541 542 543 544 545
/* kill all processes */
void kill_all_processes( struct process *skip, int exit_code )
{
    for (;;)
    {
546
        struct process *process;
547

548 549 550 551 552 553
        LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry )
        {
            if (process == skip) continue;
            if (process->running_threads) break;
        }
        if (&process->entry == &process_list) break;  /* no process found */
554 555 556 557
        kill_process( process, NULL, exit_code );
    }
}

558
/* kill all processes being attached to a console renderer */
559
void kill_console_processes( struct thread *renderer, int exit_code )
560 561 562
{
    for (;;)  /* restart from the beginning of the list every time */
    {
563
        struct process *process;
564 565

        /* find the first process being attached to 'renderer' and still running */
566
        LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry )
567
        {
568 569 570
            if (process == renderer->process) continue;
            if (!process->running_threads) continue;
            if (process->console && process->console->renderer == renderer) break;
571
        }
572
        if (&process->entry == &process_list) break;  /* no process found */
573 574 575 576
        kill_process( process, NULL, exit_code );
    }
}

Alexandre Julliard's avatar
Alexandre Julliard committed
577
/* a process has been killed (i.e. its last thread died) */
578
static void process_killed( struct process *process )
Alexandre Julliard's avatar
Alexandre Julliard committed
579
{
580
    struct handle_table *handles;
581 582
    struct list *ptr;

583
    assert( list_empty( &process->thread_list ));
Alexandre Julliard's avatar
Alexandre Julliard committed
584
    gettimeofday( &process->end_time, NULL );
585
    handles = process->handles;
586
    process->handles = NULL;
587
    if (handles) release_object( handles );
588 589

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

592
    while ((ptr = list_head( &process->dlls )))
593
    {
594
        struct process_dll *dll = LIST_ENTRY( ptr, struct process_dll, entry );
595
        if (dll->file) release_object( dll->file );
596
        if (dll->filename) free( dll->filename );
597
        list_remove( &dll->entry );
598 599
        free( dll );
    }
600
    destroy_process_classes( process );
601
    remove_process_locks( process );
602
    set_process_startup_state( process, STARTUP_ABORTED );
603 604
    if (process->exe.file) release_object( process->exe.file );
    process->exe.file = NULL;
Alexandre Julliard's avatar
Alexandre Julliard committed
605
    wake_up( &process->obj, 0 );
606
    if (!--running_processes) close_master_socket();
Alexandre Julliard's avatar
Alexandre Julliard committed
607 608 609 610 611
}

/* add a thread to a process running threads list */
void add_process_thread( struct process *process, struct thread *thread )
{
612
    list_add_head( &process->thread_list, &thread->proc_entry );
613
    if (!process->running_threads++) running_processes++;
Alexandre Julliard's avatar
Alexandre Julliard committed
614 615 616 617 618 619 620
    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 );
621
    assert( !list_empty( &process->thread_list ));
Alexandre Julliard's avatar
Alexandre Julliard committed
622

623
    list_remove( &thread->proc_entry );
Alexandre Julliard's avatar
Alexandre Julliard committed
624 625 626 627

    if (!--process->running_threads)
    {
        /* we have removed the last running thread, exit the process */
628 629 630
        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
631
    }
632
    else generate_debug_event( thread, EXIT_THREAD_DEBUG_EVENT, thread );
Alexandre Julliard's avatar
Alexandre Julliard committed
633 634 635
    release_object( thread );
}

636 637 638 639 640
/* suspend all the threads of a process */
void suspend_process( struct process *process )
{
    if (!process->suspend++)
    {
641 642 643
        struct list *ptr, *next;

        LIST_FOR_EACH_SAFE( ptr, next, &process->thread_list )
644
        {
645
            struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );
646
            if (!thread->suspend) stop_thread( thread );
647 648 649 650 651 652 653 654 655 656
        }
    }
}

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

        LIST_FOR_EACH_SAFE( ptr, next, &process->thread_list )
660
        {
661
            struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );
662
            if (!thread->suspend) wake_thread( thread );
663 664 665 666
        }
    }
}

Alexandre Julliard's avatar
Alexandre Julliard committed
667
/* kill a process on the spot */
668
void kill_process( struct process *process, struct thread *skip, int exit_code )
Alexandre Julliard's avatar
Alexandre Julliard committed
669
{
670
    struct list *ptr, *next;
671

672
    LIST_FOR_EACH_SAFE( ptr, next, &process->thread_list )
673
    {
674 675
        struct thread *thread = LIST_ENTRY( ptr, struct thread, proc_entry );

676 677 678
        thread->exit_code = exit_code;
        if (thread != skip) kill_thread( thread, 1 );
    }
Alexandre Julliard's avatar
Alexandre Julliard committed
679 680
}

681 682 683 684 685
/* 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 */
    {
686 687
        struct process *process;

688
        /* find the first process being debugged by 'debugger' and still running */
689 690 691 692 693 694
        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 */
695
        process->debugger = NULL;
696
        kill_process( process, NULL, exit_code );
697 698 699
    }
}

700

701 702 703 704
/* detach a debugger from all its debuggees */
void detach_debugged_processes( struct thread *debugger )
{
    struct process *process;
705 706

    LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry )
707 708 709 710 711 712 713 714 715
    {
        if (process->debugger == debugger && process->running_threads)
        {
            debugger_detach( process, debugger );
        }
    }
}


716 717
void enum_processes( int (*cb)(struct process*, void*), void *user )
{
718 719 720
    struct list *ptr, *next;

    LIST_FOR_EACH_SAFE( ptr, next, &process_list )
721
    {
722
        struct process *process = LIST_ENTRY( ptr, struct process, entry );
723 724 725 726 727
        if ((cb)(process, user)) break;
    }
}


728
/* read data from a process memory space */
729 730
/* len is the total size (in ints) */
static int read_process_memory( struct process *process, const int *addr, size_t len, int *dest )
731
{
732
    struct thread *thread = get_process_first_thread( process );
733

734 735
    assert( !((unsigned int)addr % sizeof(int)) );  /* address must be aligned */

736 737 738
    if (!thread)  /* process is dead */
    {
        set_error( STATUS_ACCESS_DENIED );
739
        return 0;
740
    }
741
    if (suspend_for_ptrace( thread ))
742
    {
743
        while (len > 0)
744
        {
745
            if (read_thread_int( thread, addr++, dest++ ) == -1) break;
746 747
            len--;
        }
748
        resume_after_ptrace( thread );
749
    }
750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
    return !len;
}

/* make sure we can write to the whole address range */
/* len is the total size (in ints) */
static int check_process_write_access( struct thread *thread, int *addr, size_t len )
{
    int page = get_page_size() / sizeof(int);

    for (;;)
    {
        if (write_thread_int( thread, addr, 0, 0 ) == -1) return 0;
        if (len <= page) break;
        addr += page;
        len -= page;
    }
    return (write_thread_int( thread, addr + len - 1, 0, 0 ) != -1);
767 768 769 770 771
}

/* write data to a process memory space */
/* len is the total size (in ints), max is the size we can actually read from the input buffer */
/* we check the total size for write permissions */
772 773
static int write_process_memory( struct process *process, int *addr, size_t len,
                                 unsigned int first_mask, unsigned int last_mask, const int *src )
774
{
775
    struct thread *thread = get_process_first_thread( process );
776
    int ret = 0;
777

778 779
    assert( !((unsigned int)addr % sizeof(int) ));  /* address must be aligned */

780 781 782
    if (!thread)  /* process is dead */
    {
        set_error( STATUS_ACCESS_DENIED );
783
        return 0;
784
    }
785
    if (suspend_for_ptrace( thread ))
786
    {
787 788 789
        if (!check_process_write_access( thread, addr, len ))
        {
            set_error( STATUS_ACCESS_DENIED );
790
            goto done;
791
        }
792 793 794
        /* first word is special */
        if (len > 1)
        {
795
            if (write_thread_int( thread, addr++, *src++, first_mask ) == -1) goto done;
796 797 798 799
            len--;
        }
        else last_mask &= first_mask;

800
        while (len > 1)
801
        {
802
            if (write_thread_int( thread, addr++, *src++, ~0 ) == -1) goto done;
803 804 805
            len--;
        }

806 807
        /* last word is special too */
        if (write_thread_int( thread, addr, *src, last_mask ) == -1) goto done;
808
        ret = 1;
809

810
    done:
811
        resume_after_ptrace( thread );
812
    }
813 814 815 816 817 818 819 820 821 822 823 824
    return ret;
}

/* set the debugged flag in the process PEB */
int set_process_debug_flag( struct process *process, int flag )
{
    int mask = 0, data = 0;

    /* BeingDebugged flag is the byte at offset 2 in the PEB */
    memset( (char *)&mask + 2, 0xff, 1 );
    memset( (char *)&data + 2, flag, 1 );
    return write_process_memory( process, process->peb, 1, mask, mask, &data );
825 826
}

827 828 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;
    if (!running_processes) return NULL;
    if (!(snapshot = mem_alloc( sizeof(*snapshot) * running_processes )))
        return NULL;
    ptr = snapshot;
836
    LIST_FOR_EACH_ENTRY( process, &process_list, struct process, entry )
837 838 839 840
    {
        if (!process->running_threads) continue;
        ptr->process  = process;
        ptr->threads  = process->running_threads;
841
        ptr->count    = process->obj.refcount;
842
        ptr->priority = process->priority;
843
        ptr->handles  = get_handle_table_count(process);
844 845 846 847 848 849
        grab_object( process );
        ptr++;
    }
    *count = running_processes;
    return snapshot;
}
850

851 852 853 854 855
/* 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;
856
    int total = 1;
857

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

861 862 863 864 865 866 867 868
    /* first entry is main exe */
    snapshot->base     = process->exe.base;
    snapshot->size     = process->exe.size;
    snapshot->namelen  = process->exe.namelen;
    snapshot->filename = memdup( process->exe.filename, process->exe.namelen );
    ptr = snapshot + 1;

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


881 882 883
/* create a new process */
DECL_HANDLER(new_process)
{
884
    struct startup_info *info;
885

886
    /* build the startup info for a new process */
887
    if (!(info = alloc_object( &startup_info_ops ))) return;
888
    list_add_head( &startup_info_list, &info->entry );
889 890
    info->inherit_all  = req->inherit_all;
    info->create_flags = req->create_flags;
891
    info->unix_pid     = req->unix_pid;
892 893 894
    info->hstdin       = req->hstdin;
    info->hstdout      = req->hstdout;
    info->hstderr      = req->hstderr;
895
    info->exe_file     = NULL;
896
    info->owner        = (struct thread *)grab_object( current );
897 898
    info->process      = NULL;
    info->thread       = NULL;
899 900
    info->data_size    = get_req_data_size();
    info->data         = NULL;
901

902
    if (req->exe_file &&
903
        !(info->exe_file = get_file_obj( current->process, req->exe_file, FILE_READ_DATA )))
904 905
        goto done;

906
    if (!(info->data = memdup( get_req_data(), info->data_size ))) goto done;
907
    reply->info = alloc_handle( current->process, info, SYNCHRONIZE, 0 );
908 909 910

 done:
    release_object( info );
911
}
912

913 914
/* Retrieve information about a newly started process */
DECL_HANDLER(get_new_process_info)
915
{
916 917 918 919
    struct startup_info *info;

    if ((info = (struct startup_info *)get_handle_obj( current->process, req->info,
                                                       0, &startup_info_ops )))
920
    {
921 922 923
        reply->pid = get_process_id( info->process );
        reply->tid = get_thread_id( info->thread );
        reply->phandle = alloc_handle( current->process, info->process,
924
                                       req->process_access, req->process_attr );
925
        reply->thandle = alloc_handle( current->process, info->thread,
926
                                       req->thread_access, req->thread_attr );
927
        reply->success = is_process_init_done( info->process );
928
        release_object( info );
929 930 931
    }
    else
    {
932 933 934 935
        reply->pid     = 0;
        reply->tid     = 0;
        reply->phandle = 0;
        reply->thandle = 0;
936
        reply->success = 0;
937
    }
938 939
}

940 941 942
/* Retrieve the new process startup info */
DECL_HANDLER(get_startup_info)
{
943 944 945
    struct process *process = current->process;
    struct startup_info *info = process->startup_info;
    size_t size;
946

947 948 949 950 951 952 953 954 955
    if (!info) return;

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

    if (!info->inherit_all && !(info->create_flags & CREATE_NEW_CONSOLE))
    {
        struct process *parent_process = info->owner->process;
        reply->hstdin  = duplicate_handle( parent_process, info->hstdin, process,
956
                                           0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
957
        reply->hstdout = duplicate_handle( parent_process, info->hstdout, process,
958
                                           0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
959
        reply->hstderr = duplicate_handle( parent_process, info->hstderr, process,
960
                                           0, OBJ_INHERIT, DUPLICATE_SAME_ACCESS );
961 962 963
        /* 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();
964
    }
965 966 967 968 969 970 971 972 973 974 975 976 977
    else
    {
        reply->hstdin  = info->hstdin;
        reply->hstdout = info->hstdout;
        reply->hstderr = info->hstderr;
    }

    /* 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;
978 979
}

980 981 982
/* signal the end of the process initialization */
DECL_HANDLER(init_process_done)
{
983
    struct file *file = NULL;
984
    struct process *process = current->process;
985

986
    if (is_process_init_done(process))
987
    {
988 989 990 991 992 993
        fatal_protocol_error( current, "init_process_done: called twice\n" );
        return;
    }
    if (!req->module)
    {
        fatal_protocol_error( current, "init_process_done: module base address cannot be 0\n" );
994 995
        return;
    }
996
    process->exe.base = req->module;
997
    process->exe.size = req->module_size;
998
    process->exe.name = req->name;
999

1000
    if (req->exe_file) file = get_file_obj( process, req->exe_file, FILE_READ_DATA );
1001 1002 1003
    if (process->exe.file) release_object( process->exe.file );
    process->exe.file = file;

1004 1005 1006
    if ((process->exe.namelen = get_req_data_size()))
        process->exe.filename = memdup( get_req_data(), process->exe.namelen );

1007 1008 1009
    generate_startup_debug_events( process, req->entry );
    set_process_startup_state( process, STARTUP_DONE );

1010
    if (req->gui) process->idle_event = create_event( NULL, NULL, 0, 1, 0 );
1011
    if (current->suspend + process->suspend > 0) stop_thread( current );
1012
    if (process->debugger) set_process_debug_flag( process, 1 );
1013 1014
}

1015 1016 1017 1018
/* open a handle to a process */
DECL_HANDLER(open_process)
{
    struct process *process = get_process_from_id( req->pid );
1019
    reply->handle = 0;
1020 1021
    if (process)
    {
1022
        reply->handle = alloc_handle( current->process, process, req->access, req->attributes );
1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033
        release_object( process );
    }
}

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

    if ((process = get_process_from_handle( req->handle, PROCESS_TERMINATE )))
    {
1034
        reply->self = (current->process == process);
1035
        kill_process( process, current, req->exit_code );
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
        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 )))
    {
1047
        reply->pid              = get_process_id( process );
1048
        reply->ppid             = process->parent ? get_process_id( process->parent ) : 0;
1049 1050
        reply->exit_code        = process->exit_code;
        reply->priority         = process->priority;
1051
        reply->affinity         = process->affinity;
1052
        reply->peb              = process->peb;
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063
        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 )))
    {
1064 1065 1066 1067 1068 1069
        if (req->mask & SET_PROCESS_INFO_PRIORITY) process->priority = req->priority;
        if (req->mask & SET_PROCESS_INFO_AFFINITY)
        {
            if (req->affinity != 1) set_error( STATUS_INVALID_PARAMETER );
            else process->affinity = req->affinity;
        }
1070 1071 1072
        release_object( process );
    }
}
1073 1074 1075 1076 1077

/* read data from a process address space */
DECL_HANDLER(read_process_memory)
{
    struct process *process;
1078
    size_t len = get_reply_max_size();
1079

1080 1081 1082
    if (!(process = get_process_from_handle( req->handle, PROCESS_VM_READ ))) return;

    if (len)
1083
    {
1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097
        unsigned int start_offset = (unsigned int)req->addr % sizeof(int);
        unsigned int nb_ints = (len + start_offset + sizeof(int) - 1) / sizeof(int);
        const int *start = (int *)((char *)req->addr - start_offset);
        int *buffer = mem_alloc( nb_ints * sizeof(int) );
        if (buffer)
        {
            if (read_process_memory( process, start, nb_ints, buffer ))
            {
                /* move start of requested data to start of buffer */
                if (start_offset) memmove( buffer, (char *)buffer + start_offset, len );
                set_reply_data_ptr( buffer, len );
            }
            else len = 0;
        }
1098
    }
1099
    release_object( process );
1100
}
1101 1102 1103 1104 1105 1106 1107 1108

/* 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 )))
    {
1109 1110 1111 1112 1113 1114 1115 1116
        size_t len = get_req_data_size();
        if ((len % sizeof(int)) || ((unsigned int)req->addr % sizeof(int)))
            set_error( STATUS_INVALID_PARAMETER );
        else
        {
            if (len) write_process_memory( process, req->addr, len / sizeof(int),
                                           req->first_mask, req->last_mask, get_req_data() );
        }
1117 1118 1119
        release_object( process );
    }
}
1120 1121 1122 1123 1124 1125 1126

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

1127
    if (req->handle && !(file = get_file_obj( current->process, req->handle, FILE_READ_DATA )))
1128
        return;
1129

1130 1131
    if ((dll = process_load_dll( current->process, file, req->base,
                                 get_req_data(), get_req_data_size() )))
1132
    {
1133
        dll->size       = req->size;
1134 1135 1136 1137
        dll->dbg_offset = req->dbg_offset;
        dll->dbg_size   = req->dbg_size;
        dll->name       = req->name;
        /* only generate event if initialization is done */
1138
        if (is_process_init_done( current->process ))
1139 1140 1141 1142 1143 1144 1145 1146 1147 1148
            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 );
}
1149

1150 1151 1152 1153 1154 1155 1156
/* 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 )))
    {
1157
        struct process_dll *dll = find_process_dll( process, req->base_address );
1158

1159
        if (dll)
1160
        {
1161
            reply->size = dll->size;
1162
            reply->entry_point = NULL; /* FIXME */
1163
            if (dll->filename)
1164
            {
1165 1166
                size_t len = min( dll->namelen, get_reply_max_size() );
                set_reply_data( dll->filename, len );
1167 1168
            }
        }
1169 1170 1171
        else
            set_error( STATUS_DLL_NOT_FOUND );

1172 1173 1174 1175
        release_object( process );
    }
}

1176 1177 1178 1179 1180 1181
/* wait for a process to start waiting on input */
/* FIXME: only returns event for now, wait is done in the client */
DECL_HANDLER(wait_input_idle)
{
    struct process *process;

1182
    reply->event = 0;
1183 1184
    if ((process = get_process_from_handle( req->handle, PROCESS_QUERY_INFORMATION )))
    {
1185
        if (process->idle_event && process != current->process)
1186 1187
            reply->event = alloc_handle( current->process, process->idle_event,
                                         EVENT_ALL_ACCESS, 0 );
1188 1189 1190
        release_object( process );
    }
}