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

#include <assert.h>
#include <stdio.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)
            fprintf( stderr, "Warning: 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;
}
