/*
 * Server-side process management
 *
 * Copyright (C) 1998 Alexandre Julliard
 */

#include <assert.h>
#include <limits.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>

#include "winerror.h"
#include "winbase.h"
#include "winnt.h"

#include "server.h"
#include "server/thread.h"

/* reserved handle access rights */
#define RESERVED_SHIFT         25
#define RESERVED_INHERIT       (HANDLE_FLAG_INHERIT << RESERVED_SHIFT)
#define RESERVED_CLOSE_PROTECT (HANDLE_FLAG_PROTECT_FROM_CLOSE << RESERVED_SHIFT)
#define RESERVED_ALL           (RESERVED_INHERIT | RESERVED_CLOSE_PROTECT)

/* global handle macros */
#define HANDLE_OBFUSCATOR         0x544a4def
#define HANDLE_IS_GLOBAL(h)       (((h) ^ HANDLE_OBFUSCATOR) < 0x10000)
#define HANDLE_LOCAL_TO_GLOBAL(h) ((h) ^ HANDLE_OBFUSCATOR)
#define HANDLE_GLOBAL_TO_LOCAL(h) ((h) ^ HANDLE_OBFUSCATOR)

struct handle_entry
{
    struct object *ptr;
    unsigned int   access;
};

/* process structure; not much for now... */

struct process
{
    struct object        obj;             /* object header */
    struct process      *next;            /* system-wide process list */
    struct process      *prev;
    struct thread       *thread_list;     /* head of the thread list */
    struct handle_entry *entries;         /* handle entry table */
    int                  handle_count;    /* nb of allocated handle entries */
    int                  handle_last;     /* last used handle entry */
    int                  exit_code;       /* process exit code */
    int                  running_threads; /* number of threads running in this process */
    struct timeval       start_time;      /* absolute time at process start */
    struct timeval       end_time;        /* absolute time at process end */
};

static struct process *first_process;
static struct process *initial_process;

#define MIN_HANDLE_ENTRIES  32

/* process operations */

static void process_dump( struct object *obj, int verbose );
static int process_signaled( struct object *obj, struct thread *thread );
static void process_destroy( struct object *obj );
static void free_handles( struct process *process );
static int copy_handle_table( struct process *process, struct process *parent );

static const struct object_ops process_ops =
{
    process_dump,
    add_queue,
    remove_queue,
    process_signaled,
    no_satisfied,
    no_read_fd,
    no_write_fd,
    no_flush,
    no_get_file_info,
    process_destroy
};

/* create a new process */
struct process *create_process(void)
{
    struct process *process;

    if (!(process = mem_alloc( sizeof(*process) ))) return NULL;

    if (!copy_handle_table( process, current ? current->process : NULL ))
    {
        free( process );
        return NULL;
    }
    init_object( &process->obj, &process_ops, NULL );
    process->next            = first_process;
    process->prev            = NULL;
    process->thread_list     = NULL;
    process->exit_code       = 0x103;  /* STILL_ACTIVE */
    process->running_threads = 0;

    if (first_process) first_process->prev = process;
    first_process = process;
    if (!initial_process)
    {
        initial_process = process;
        grab_object( initial_process ); /* so that we never free it */
    }

    gettimeofday( &process->start_time, NULL );
    /* alloc a handle for the process itself */
    alloc_handle( process, process, PROCESS_ALL_ACCESS, 0 );
    return process;
}

/* destroy a process when its refcount is 0 */
static void process_destroy( struct object *obj )
{
    struct process *process = (struct process *)obj;
    assert( obj->ops == &process_ops );
    assert( process != initial_process );

    /* we can't have a thread remaining */
    assert( !process->thread_list );
    if (process->next) process->next->prev = process->prev;
    if (process->prev) process->prev->next = process->next;
    else first_process = process->next;
    free_handles( process );
    if (debug_level) memset( process, 0xbb, sizeof(process) );  /* catch errors */
    free( process );
}

/* dump a process on stdout for debugging purposes */
static void process_dump( struct object *obj, int verbose )
{
    struct process *process = (struct process *)obj;
    assert( obj->ops == &process_ops );

    printf( "Process next=%p prev=%p\n", process->next, process->prev );
}

static int process_signaled( struct object *obj, struct thread *thread )
{
    struct process *process = (struct process *)obj;
    return (process->running_threads > 0);
}

/* get a process from an id (and increment the refcount) */
struct process *get_process_from_id( void *id )
{
    struct process *p = first_process;
    while (p && (p != id)) p = p->next;
    if (p) grab_object( p );
    else SET_ERROR( ERROR_INVALID_PARAMETER );
    return p;
}

/* get a process from a handle (and increment the refcount) */
struct process *get_process_from_handle( int handle, unsigned int access )
{
    return (struct process *)get_handle_obj( current->process, handle,
                                             access, &process_ops );
}

/* a process has been killed (i.e. its last thread died) */
static void process_killed( struct process *process, int exit_code )
{
    assert( !process->thread_list );
    process->exit_code = exit_code;
    gettimeofday( &process->end_time, NULL );
    wake_up( &process->obj, 0 );
    free_handles( process );
}

/* free the process handle entries */
static void free_handles( struct process *process )
{
    struct handle_entry *entry;
    int handle;

    if (!(entry = process->entries)) return;
    for (handle = 0; handle <= process->handle_last; handle++, entry++)
    {
        struct object *obj = entry->ptr;
        entry->ptr = NULL;
        if (obj) release_object( obj );
    }
    free( process->entries );
    process->handle_count = 0;
    process->handle_last  = -1;
    process->entries = NULL;
}

/* add a thread to a process running threads list */
void add_process_thread( struct process *process, struct thread *thread )
{
    thread->proc_next = process->thread_list;
    thread->proc_prev = NULL;
    if (thread->proc_next) thread->proc_next->proc_prev = thread;
    process->thread_list = thread;
    process->running_threads++;
    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 );
    assert( process->thread_list );

    if (thread->proc_next) thread->proc_next->proc_prev = thread->proc_prev;
    if (thread->proc_prev) thread->proc_prev->proc_next = thread->proc_next;
    else process->thread_list = thread->proc_next;

    if (!--process->running_threads)
    {
        /* we have removed the last running thread, exit the process */
        process_killed( process, thread->exit_code );
    }
    release_object( thread );
}

/* grow a handle table */
/* return 1 if OK, 0 on error */
static int grow_handle_table( struct process *process )
{
    struct handle_entry *new_entries;
    int count = process->handle_count;

    if (count >= INT_MAX / 2) return 0;
    count *= 2;
    if (!(new_entries = realloc( process->entries, count * sizeof(struct handle_entry) )))
    {
        SET_ERROR( ERROR_OUTOFMEMORY );
        return 0;
    }
    process->handle_count = count;
    process->entries      = new_entries;
    return 1;
}

/* allocate a handle for an object, incrementing its refcount */
/* return the handle, or -1 on error */
int alloc_handle( struct process *process, void *obj, unsigned int access,
                  int inherit )
{
    struct handle_entry *entry;
    int handle;

    assert( !(access & RESERVED_ALL) );
    if (inherit) access |= RESERVED_INHERIT;

    /* find the first free entry */

    if (!(entry = process->entries)) return -1;
    for (handle = 0; handle <= process->handle_last; handle++, entry++)
        if (!entry->ptr) goto found;

    if (handle >= process->handle_count)
    {
        if (!grow_handle_table( process )) return -1;
        entry = process->entries + handle;  /* the table may have moved */
    }
    process->handle_last = handle;

 found:
    entry->ptr    = grab_object( obj );
    entry->access = access;
    return handle + 1;  /* avoid handle 0 */
}

/* allocate a specific handle for an object, incrementing its refcount */
static int alloc_specific_handle( struct process *process, void *obj, int handle,
                                  unsigned int access, int inherit )
{
    struct handle_entry *entry;
    struct object *old;

    if (handle == -1) return alloc_handle( process, obj, access, inherit );

    assert( !(access & RESERVED_ALL) );
    if (inherit) access |= RESERVED_INHERIT;

    handle--;  /* handles start at 1 */
    if ((handle < 0) || (handle > process->handle_last))
    {
        SET_ERROR( ERROR_INVALID_HANDLE );
        return -1;
    }
    entry = process->entries + handle;

    old = entry->ptr;
    entry->ptr = grab_object( obj );
    entry->access = access;
    if (old) release_object( old );
    return handle + 1;
}

/* return an handle entry, or NULL if the handle is invalid */
static struct handle_entry *get_handle( struct process *process, int handle )
{
    struct handle_entry *entry;

    if (HANDLE_IS_GLOBAL(handle))
    {
        handle = HANDLE_GLOBAL_TO_LOCAL(handle);
        process = initial_process;
    }
    handle--;  /* handles start at 1 */
    if ((handle < 0) || (handle > process->handle_last)) goto error;
    entry = process->entries + handle;
    if (!entry->ptr) goto error;
    return entry;

 error:
    SET_ERROR( ERROR_INVALID_HANDLE );
    return NULL;
}

/* attempt to shrink a table */
/* return 1 if OK, 0 on error */
static int shrink_handle_table( struct process *process )
{
    struct handle_entry *new_entries;
    struct handle_entry *entry = process->entries + process->handle_last;
    int count = process->handle_count;

    while (process->handle_last >= 0)
    {
        if (entry->ptr) break;
        process->handle_last--;
        entry--;
    }
    if (process->handle_last >= count / 4) return 1;  /* no need to shrink */
    if (count < MIN_HANDLE_ENTRIES * 2) return 1;  /* too small to shrink */
    count /= 2;
    if (!(new_entries = realloc( process->entries,
                                 count * sizeof(struct handle_entry) )))
        return 0;
    process->handle_count = count;
    process->entries      = new_entries;
    return 1;
}

/* copy the handle table of the parent process */
/* return 1 if OK, 0 on error */
static int copy_handle_table( struct process *process, struct process *parent )
{
    struct handle_entry *ptr;
    int i, count, last;

    if (!parent)  /* first process */
    {
        count = MIN_HANDLE_ENTRIES;
        last  = -1;
    }
    else
    {
        assert( parent->entries );
        count = parent->handle_count;
        last  = parent->handle_last;
    }

    if (!(ptr = mem_alloc( count * sizeof(struct handle_entry)))) return 0;
    process->entries      = ptr;
    process->handle_count = count;
    process->handle_last  = last;

    if (last >= 0)
    {
        memcpy( ptr, parent->entries, (last + 1) * sizeof(struct handle_entry) );
        for (i = 0; i <= last; i++, ptr++)
        {
            if (!ptr->ptr) continue;
            if (ptr->access & RESERVED_INHERIT) grab_object( ptr->ptr );
            else ptr->ptr = NULL; /* don't inherit this entry */
        }
    }
    /* attempt to shrink the table */
    shrink_handle_table( process );
    return 1;
}

/* close a handle and decrement the refcount of the associated object */
/* return 1 if OK, 0 on error */
int close_handle( struct process *process, int handle )
{
    struct handle_entry *entry;
    struct object *obj;

    if (HANDLE_IS_GLOBAL(handle))
    {
        handle = HANDLE_GLOBAL_TO_LOCAL(handle);
        process = initial_process;
    }
    if (!(entry = get_handle( process, handle ))) return 0;
    if (entry->access & RESERVED_CLOSE_PROTECT) return 0;  /* FIXME: error code */
    obj = entry->ptr;
    entry->ptr = NULL;
    if (handle-1 == process->handle_last) shrink_handle_table( process );
    release_object( obj );
    return 1;
}

/* retrieve the object corresponding to a handle, incrementing its refcount */
struct object *get_handle_obj( struct process *process, int handle,
                               unsigned int access, const struct object_ops *ops )
{
    struct handle_entry *entry;
    struct object *obj;

    switch( handle )
    {
    case 0xfffffffe:  /* current thread pseudo-handle */
        obj = &current->obj;
        break;
    case 0x7fffffff:  /* current process pseudo-handle */
        obj = (struct object *)current->process;
        break;
    default:
        if (!(entry = get_handle( process, handle ))) return NULL;
        if ((entry->access & access) != access)
        {
            SET_ERROR( ERROR_ACCESS_DENIED );
            return NULL;
        }
        obj = entry->ptr;
        break;
    }
    if (ops && (obj->ops != ops))
    {
        SET_ERROR( ERROR_INVALID_HANDLE );  /* not the right type */
        return NULL;
    }
    return grab_object( obj );
}

/* get/set the handle reserved flags */
/* return the new flags (or -1 on error) */
int set_handle_info( struct process *process, int handle, int mask, int flags )
{
    struct handle_entry *entry;

    if (!(entry = get_handle( process, handle ))) return -1;
    mask  = (mask << RESERVED_SHIFT) & RESERVED_ALL;
    flags = (flags << RESERVED_SHIFT) & mask;
    entry->access = (entry->access & ~mask) | flags;
    return (entry->access & RESERVED_ALL) >> RESERVED_SHIFT;
}

/* duplicate a handle */
int duplicate_handle( struct process *src, int src_handle, struct process *dst,
                      int dst_handle, unsigned int access, int inherit, int options )
{
    int res;
    struct handle_entry *entry = get_handle( src, src_handle );
    if (!entry) return -1;

    if (options & DUP_HANDLE_SAME_ACCESS) access = entry->access;
    if (options & DUP_HANDLE_MAKE_GLOBAL) dst = initial_process;
    access &= ~RESERVED_ALL;
    res = alloc_specific_handle( dst, entry->ptr, dst_handle, access, inherit );
    if (options & DUP_HANDLE_MAKE_GLOBAL) res = HANDLE_LOCAL_TO_GLOBAL(res);
    return res;
}

/* open a new handle to an existing object */
int open_object( const char *name, const struct object_ops *ops,
                 unsigned int access, int inherit )
{
    struct object *obj = find_object( name );
    if (!obj) return -1;  /* FIXME: set error code */
    if (ops && obj->ops != ops)
    {
        release_object( obj );
        return -1;  /* FIXME: set error code */
    }
    return alloc_handle( current->process, obj, access, inherit );
}

/* dump a handle table on stdout */
void dump_handles( struct process *process )
{
    struct handle_entry *entry;
    int i;

    if (!process->entries) return;
    entry = process->entries;
    for (i = 0; i <= process->handle_last; i++, entry++)
    {
        if (!entry->ptr) continue;
        printf( "%5d: %p %08x ", i + 1, entry->ptr, entry->access );
        entry->ptr->ops->dump( entry->ptr, 0 );
    }
}

/* kill a process on the spot */
void kill_process( struct process *process, int exit_code )
{
    while (process->thread_list)
        kill_thread( process->thread_list, exit_code );
}

/* get all information about a process */
void get_process_info( struct process *process,
                       struct get_process_info_reply *reply )
{
    reply->pid       = process;
    reply->exit_code = process->exit_code;
}
