/*
 * Win32 process handles
 *
 * Copyright 1998 Alexandre Julliard
 */

#include <assert.h>
#include <stdio.h>
#include "debug.h"
#include "winbase.h"
#include "winerror.h"
#include "heap.h"
#include "process.h"
#include "server.h"
#include "thread.h"

#define HTABLE_SIZE  0x30  /* Handle table initial size */
#define HTABLE_INC   0x10  /* Handle table increment */

/* Reserved access rights */
#define RESERVED_ALL           (0x0007 << RESERVED_SHIFT)
#define RESERVED_SHIFT         25
#define RESERVED_INHERIT       (HANDLE_FLAG_INHERIT<<RESERVED_SHIFT)
#define RESERVED_CLOSE_PROTECT (HANDLE_FLAG_PROTECT_FROM_CLOSE<<RESERVED_SHIFT)


/***********************************************************************
 *           HANDLE_GrowTable
 */
static BOOL32 HANDLE_GrowTable( PDB32 *process, INT32 incr )
{
    HANDLE_TABLE *table;

    SYSTEM_LOCK();
    table = process->handle_table;
    table = HeapReAlloc( process->system_heap,
                         HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE, table,
                         sizeof(HANDLE_TABLE) +
                         (table->count + incr - 1) * sizeof(HANDLE_ENTRY) );
    if (table)
    {
        table->count += incr;
        process->handle_table = table;
    }
    SYSTEM_UNLOCK();
    return (table != NULL);
}


/***********************************************************************
 *           HANDLE_CreateTable
 *
 * Create a process handle table, optionally inheriting the parent's handles.
 */
BOOL32 HANDLE_CreateTable( PDB32 *pdb, BOOL32 inherit )
{
    DWORD size;

    /* Process must not already have a handle table */
    assert( !pdb->handle_table );

    /* If this is the first process, simply allocate a table */
    if (!pdb->parent) inherit = FALSE;

    SYSTEM_LOCK();
    size = inherit ? pdb->parent->handle_table->count : HTABLE_SIZE;
    if ((pdb->handle_table = HeapAlloc( pdb->system_heap,
                                        HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE,
                                        sizeof(HANDLE_TABLE) +
                                        (size-1) * sizeof(HANDLE_ENTRY) )))
    {
        pdb->handle_table->count = size;
        if (inherit)
        {
            HANDLE_ENTRY *src = pdb->parent->handle_table->entries;
            HANDLE_ENTRY *dst = pdb->handle_table->entries;
            HANDLE32 h;

            for (h = 0; h < size; h++, src++, dst++)
            {
                /* Check if handle is valid and inheritable */
                if (src->ptr && (src->access & RESERVED_INHERIT))
                {
                    dst->access = src->access;
                    dst->ptr    = src->ptr;
                    dst->server = src->server;
                    K32OBJ_IncCount( dst->ptr );
                }
            }
        }
        /* Handle 1 is the process itself (unless the parent decided otherwise) */
        if (!pdb->handle_table->entries[1].ptr)
        {
            pdb->handle_table->entries[1].ptr    = &pdb->header;
            pdb->handle_table->entries[1].access = PROCESS_ALL_ACCESS;
            pdb->handle_table->entries[1].server = -1;  /* FIXME */
            K32OBJ_IncCount( &pdb->header );
        }
    }
    SYSTEM_UNLOCK();
    return (pdb->handle_table != NULL);
}


/***********************************************************************
 *           HANDLE_Alloc
 *
 * Allocate a handle for a kernel object and increment its refcount.
 */
HANDLE32 HANDLE_Alloc( PDB32 *pdb, K32OBJ *ptr, DWORD access,
                       BOOL32 inherit, int server_handle )
{
    HANDLE32 h;
    HANDLE_ENTRY *entry;

    assert( ptr );

    /* Set the inherit reserved flag */
    access &= ~RESERVED_ALL;
    if (inherit) access |= RESERVED_INHERIT;

    SYSTEM_LOCK();
    K32OBJ_IncCount( ptr );
    /* Don't try to allocate handle 0 */
    entry = pdb->handle_table->entries + 1;
    for (h = 1; h < pdb->handle_table->count; h++, entry++)
        if (!entry->ptr) break;
    if ((h < pdb->handle_table->count) || HANDLE_GrowTable( pdb, HTABLE_INC ))
    {
        entry = &pdb->handle_table->entries[h];
        entry->access = access;
        entry->ptr    = ptr;
        entry->server = server_handle;
        SYSTEM_UNLOCK();
        return h;
    }
    K32OBJ_DecCount( ptr );
    SYSTEM_UNLOCK();
    if (server_handle != -1) CLIENT_CloseHandle( server_handle );
    SetLastError( ERROR_OUTOFMEMORY );
    return INVALID_HANDLE_VALUE32;
}


/***********************************************************************
 *           HANDLE_GetObjPtr
 *
 * Retrieve a pointer to a kernel object and increments its reference count.
 * The refcount must be decremented when the pointer is no longer used.
 */
K32OBJ *HANDLE_GetObjPtr( PDB32 *pdb, HANDLE32 handle,
                          K32OBJ_TYPE type, DWORD access,
                          int *server_handle )
{
    K32OBJ *ptr = NULL;

    SYSTEM_LOCK();
    if ((handle > 0) && (handle <= pdb->handle_table->count))
    {
        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
        if ((entry->access & access) != access)
            WARN(win32, "Handle %08x bad access (acc=%08lx req=%08lx)\n",
                     handle, entry->access, access );
        ptr = entry->ptr;
        if (server_handle) *server_handle = entry->server;
    }
    else if (handle == CURRENT_THREAD_PSEUDOHANDLE)
    {
       ptr = (K32OBJ *)THREAD_Current();
       if (server_handle) *server_handle = CURRENT_THREAD_PSEUDOHANDLE;
    }
    else if (handle == CURRENT_PROCESS_PSEUDOHANDLE)
    {
       ptr = (K32OBJ *)PROCESS_Current();
       if (server_handle) *server_handle = CURRENT_PROCESS_PSEUDOHANDLE;
    }

    if (ptr && ((type == K32OBJ_UNKNOWN) || (ptr->type == type)))
        K32OBJ_IncCount( ptr );
    else
        ptr = NULL;

    SYSTEM_UNLOCK();
    if (!ptr) SetLastError( ERROR_INVALID_HANDLE );
    return ptr;
}


/***********************************************************************
 *           HANDLE_SetObjPtr
 *
 * Change the object pointer of a handle, and increment the refcount.
 * Use with caution!
 */
BOOL32 HANDLE_SetObjPtr( PDB32 *pdb, HANDLE32 handle, K32OBJ *ptr,
                         DWORD access )
{
    BOOL32 ret = FALSE;

    SYSTEM_LOCK();
    if ((handle > 0) && (handle <= pdb->handle_table->count))
    {
        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
        K32OBJ *old_ptr = entry->ptr;
        K32OBJ_IncCount( ptr );
        entry->access = access;
        entry->ptr    = ptr;
        if (old_ptr) K32OBJ_DecCount( old_ptr );
        ret = TRUE;
    }
    SYSTEM_UNLOCK();
    if (!ret) SetLastError( ERROR_INVALID_HANDLE );
    return ret;
}


/*********************************************************************
 *           HANDLE_GetAccess
 */
static BOOL32 HANDLE_GetAccess( PDB32 *pdb, HANDLE32 handle, LPDWORD access )
{
    BOOL32 ret = FALSE;

    SYSTEM_LOCK();
    if ((handle > 0) && (handle <= pdb->handle_table->count))
    {
        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
        if (entry->ptr)
        {
            *access = entry->access & ~RESERVED_ALL;
            ret = TRUE;
        }
    }
    SYSTEM_UNLOCK();
    if (!ret) SetLastError( ERROR_INVALID_HANDLE );
    return ret;
}


/*********************************************************************
 *           HANDLE_Close
 */
static BOOL32 HANDLE_Close( PDB32 *pdb, HANDLE32 handle )
{
    BOOL32 ret = FALSE;
    K32OBJ *ptr;

    SYSTEM_LOCK();
    if ((handle > 0) && (handle <= pdb->handle_table->count))
    {
        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
        if ((ptr = entry->ptr))
        {
            if (!(entry->access & RESERVED_CLOSE_PROTECT))
            {
                entry->access = 0;
                entry->ptr    = NULL;
                if (entry->server != -1)
                    CLIENT_CloseHandle( entry->server );
                K32OBJ_DecCount( ptr );
                ret = TRUE;
            }
            /* FIXME: else SetLastError */
        }
    }
    SYSTEM_UNLOCK();
    if (!ret) SetLastError( ERROR_INVALID_HANDLE );
    return ret;
}


/*********************************************************************
 *           HANDLE_CloseAll
 *
 * Close all handles pointing to a given object (or all handles of the
 * process if the object is NULL)
 */
void HANDLE_CloseAll( PDB32 *pdb, K32OBJ *obj )
{
    HANDLE_ENTRY *entry;
    K32OBJ *ptr;
    HANDLE32 handle;

    SYSTEM_LOCK();
    entry = pdb->handle_table->entries;
    for (handle = 0; handle < pdb->handle_table->count; handle++, entry++)
    {
        if (!(ptr = entry->ptr)) continue;  /* empty slot */
        if (obj && (ptr != obj)) continue;  /* not the right object */
        entry->access = 0;
        entry->ptr    = NULL;
        if (entry->server != -1) CLIENT_CloseHandle( entry->server );
        K32OBJ_DecCount( ptr );
    }
    SYSTEM_UNLOCK();
}


/*********************************************************************
 *           CloseHandle   (KERNEL32.23)
 */
BOOL32 WINAPI CloseHandle( HANDLE32 handle )
{
    return HANDLE_Close( PROCESS_Current(), handle );
}


/*********************************************************************
 *           GetHandleInformation   (KERNEL32.336)
 */
BOOL32 WINAPI GetHandleInformation( HANDLE32 handle, LPDWORD flags )
{
    BOOL32 ret = FALSE;
    PDB32 *pdb = PROCESS_Current();

    SYSTEM_LOCK();
    if ((handle > 0) && (handle <= pdb->handle_table->count))
    {
        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
        if (entry->ptr)
        {
            if (flags)
                *flags = (entry->access & RESERVED_ALL) >> RESERVED_SHIFT;
            ret = TRUE;
        }
    }
    SYSTEM_UNLOCK();
    if (!ret) SetLastError( ERROR_INVALID_HANDLE );
    return ret;
}


/*********************************************************************
 *           SetHandleInformation   (KERNEL32.653)
 */
BOOL32 WINAPI SetHandleInformation( HANDLE32 handle, DWORD mask, DWORD flags )
{
    BOOL32 ret = FALSE;
    PDB32 *pdb = PROCESS_Current();

    mask  = (mask << RESERVED_SHIFT) & RESERVED_ALL;
    flags = (flags << RESERVED_SHIFT) & RESERVED_ALL;
    SYSTEM_LOCK();
    if ((handle > 0) && (handle <= pdb->handle_table->count))
    {
        HANDLE_ENTRY *entry = &pdb->handle_table->entries[handle];
        if (entry->ptr)
        {
            entry->access = (entry->access & ~mask) | flags;
            ret = TRUE;
        }
    }
    SYSTEM_UNLOCK();
    if (!ret) SetLastError( ERROR_INVALID_HANDLE );
    return ret;
}


/*********************************************************************
 *           DuplicateHandle   (KERNEL32.192)
 */
BOOL32 WINAPI DuplicateHandle( HANDLE32 source_process, HANDLE32 source,
                               HANDLE32 dest_process, HANDLE32 *dest,
                               DWORD access, BOOL32 inherit, DWORD options )
{
    PDB32 *src_pdb = NULL, *dst_pdb = NULL;
    K32OBJ *obj = NULL;
    BOOL32 ret = FALSE;
    HANDLE32 handle;
    int src_process, src_handle, dst_process, dst_handle;

    SYSTEM_LOCK();

    if (!(src_pdb = PROCESS_GetPtr( source_process, PROCESS_DUP_HANDLE, &src_process )))
        goto done;
    if (!(obj = HANDLE_GetObjPtr( src_pdb, source, K32OBJ_UNKNOWN, 0, &src_handle )))
        goto done;

    /* Now that we are sure the source is valid, handle the options */

    if (options & DUPLICATE_SAME_ACCESS)
        HANDLE_GetAccess( src_pdb, source, &access );
    if (options & DUPLICATE_CLOSE_SOURCE)
        HANDLE_Close( src_pdb, source );

    /* And duplicate the handle in the dest process */

    if (!(dst_pdb = PROCESS_GetPtr( dest_process, PROCESS_DUP_HANDLE, &dst_process )))
        goto done;

    if ((src_process != -1) && (src_handle != -1) && (dst_process != -1))
        dst_handle = CLIENT_DuplicateHandle( src_process, src_handle, dst_process, -1,
                                             access, inherit, options );
    else
        dst_handle = -1;

    if ((handle = HANDLE_Alloc( dst_pdb, obj, access, inherit,
                                dst_handle )) != INVALID_HANDLE_VALUE32)
    {
        if (dest) *dest = handle;
        ret = TRUE;
    }

done:
    if (dst_pdb) K32OBJ_DecCount( &dst_pdb->header );
    if (obj) K32OBJ_DecCount( obj );
    if (src_pdb) K32OBJ_DecCount( &src_pdb->header );
    SYSTEM_UNLOCK();
    return ret;
}
