/*
 * 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/process.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 */
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 */
    int                  priority;        /* priority class */
    int                  affinity;        /* process affinity mask */
    struct object       *console_in;      /* console input */
    struct object       *console_out;     /* console output */
    struct new_process_request *info;     /* startup info (freed after startup) */
};


static struct process initial_process;
static struct process *first_process = &initial_process;
static int running_processes;

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


/* initialization of a process structure */
static void init_process( struct process *process )
{
    init_object( &process->obj, &process_ops, NULL );
    process->next            = NULL;
    process->prev            = NULL;
    process->thread_list     = NULL;
    process->exit_code       = 0x103;  /* STILL_ACTIVE */
    process->running_threads = 0;
    process->priority        = NORMAL_PRIORITY_CLASS;
    process->affinity        = 1;
    process->console_in      = NULL;
    process->console_out     = NULL;
    process->info            = NULL;
    gettimeofday( &process->start_time, NULL );
    /* alloc a handle for the process itself */
    alloc_handle( process, process, PROCESS_ALL_ACCESS, 0 );
}

/* create the initial process */
struct process *create_initial_process(void)
{
    struct new_process_request *info;

    copy_handle_table( &initial_process, NULL );
    init_process( &initial_process );

    if (!alloc_console( &initial_process )) return NULL;
    if (!(info = mem_alloc( sizeof(*info) ))) return NULL;
    info->start_flags = STARTF_USESTDHANDLES;
    info->hstdin  = alloc_handle( &initial_process, initial_process.console_in,
                                  GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
    info->hstdout = alloc_handle( &initial_process, initial_process.console_out,
                                  GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
    info->hstderr = alloc_handle( &initial_process, initial_process.console_out,
                                  GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, 1 );
    info->env_ptr = NULL;
    initial_process.info = info;
    grab_object( &initial_process ); /* so that we never free it */
    return &initial_process;

}

/* create a new process */
struct process *create_process( struct new_process_request *req )
{
    struct process *process = NULL;
    struct process *parent = current->process;

    if (!(process = mem_alloc( sizeof(*process) ))) return NULL;
    if (!copy_handle_table( process, req->inherit_all ? parent : NULL ))
    {
        free( process );
        return NULL;
    }
    init_process( process );
    if (parent->console_in) process->console_in = grab_object( parent->console_in );
    if (parent->console_out) process->console_out = grab_object( parent->console_out );

    if (!(process->info = mem_alloc( sizeof(*process->info) ))) goto error;
    memcpy( process->info, req, sizeof(*req) );

    if (!req->inherit_all && !(req->start_flags & STARTF_USESTDHANDLES))
    {
        process->info->hstdin  = duplicate_handle( parent, req->hstdin, process,
                                                   0, TRUE, DUPLICATE_SAME_ACCESS );
        process->info->hstdout = duplicate_handle( parent, req->hstdout, process,
                                                   0, TRUE, DUPLICATE_SAME_ACCESS );
        process->info->hstderr = duplicate_handle( parent, req->hstderr, process,
                                                   0, TRUE, DUPLICATE_SAME_ACCESS );
    }

    process->next = first_process;
    first_process->prev = process;
    first_process = process;
    return process;

 error:
    release_object( process );
    return NULL;
}

/* 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_console( process );
    free_handles( process );
    if (process->info) free( process->info );
    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;
}


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

/* retrieve the initialization info for a new process */
int get_process_init_info( struct process *process, struct init_process_reply *reply )
{
    struct new_process_request *info;
    if (!(info = process->info)) return 0;
    process->info = NULL;
    reply->start_flags = info->start_flags;
    reply->hstdin      = info->hstdin;
    reply->hstdout     = info->hstdout;
    reply->hstderr     = info->hstderr;
    reply->env_ptr     = info->env_ptr;
    free( info );
    return 1;
}

/* 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;
    if (!process->running_threads++) running_processes++;
    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 */
        running_processes--;
        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 */
}

/* 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,
                      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_handle( dst, entry->ptr, 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) 
    {
        SET_ERROR( ERROR_FILE_NOT_FOUND );
        return -1;
    }
    if (ops && obj->ops != ops)
    {
        release_object( obj );
        SET_ERROR( ERROR_INVALID_HANDLE );  /* FIXME: not the right type */ 
        return -1;
    }
    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;
    reply->priority         = process->priority;
    reply->process_affinity = process->affinity;
    reply->system_affinity  = 1;
}

/* set all information about a process */
void set_process_info( struct process *process,
                       struct set_process_info_request *req )
{
    if (req->mask & SET_PROCESS_INFO_PRIORITY)
        process->priority = req->priority;
    if (req->mask & SET_PROCESS_INFO_AFFINITY)
    {
        if (req->affinity != 1) SET_ERROR( ERROR_INVALID_PARAMETER );
        else process->affinity = req->affinity;
    }
}

/* allocate a console for this process */
int alloc_console( struct process *process )
{
    struct object *obj[2];
    if (process->console_in || process->console_out)
    {
        SET_ERROR( ERROR_ACCESS_DENIED );
        return 0;
    }
    if (!create_console( -1, obj )) return 0;
    process->console_in  = obj[0];
    process->console_out = obj[1];
    return 1;
}

/* free the console for this process */
int free_console( struct process *process )
{
    if (process->console_in) release_object( process->console_in );
    if (process->console_out) release_object( process->console_out );
    process->console_in = process->console_out = NULL;
    return 1;
}

/* get the process console */
struct object *get_console( struct process *process, int output )
{
    struct object *obj;
    if (!(obj = output ? process->console_out : process->console_in))
        return NULL;
    return grab_object( obj );
}

/* 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;
    for (process = first_process; process; process = process->next)
    {
        if (!process->running_threads) continue;
        ptr->process  = process;
        ptr->threads  = process->running_threads;
        ptr->priority = process->priority;
        grab_object( process );
        ptr++;
    }
    *count = running_processes;
    return snapshot;
}
