/*
 * 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"

#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;
                    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;
            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 )
{
    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;
        SYSTEM_UNLOCK();
        return h;
    }
    K32OBJ_DecCount( ptr );
    SYSTEM_UNLOCK();
    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 )
{
    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 (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;
                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;
        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;

    SYSTEM_LOCK();

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

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

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

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

    if (!(dst_pdb = PROCESS_GetPtr( dest_process, PROCESS_DUP_HANDLE )))
        goto done;
    if ((handle = HANDLE_Alloc( dst_pdb, obj,
                                access, inherit )) != 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;
}
