/*
 * dlls/rsaenh/handle.c
 * Support code to manage HANDLE tables.
 *
 * Copyright 1998 Alexandre Julliard
 * Copyright 2002-2004 Mike McCormack for CodeWeavers
 * Copyright 2004 Michael Jung
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <string.h>
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "handle.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(handle);

#define HANDLE2INDEX(h) ((h)-1)
#define INDEX2HANDLE(i) ((i)+1)

/******************************************************************************
 *  init_handle_table
 *
 * Initializes the HANDLETABLE structure pointed to by lpTable
 *
 * PARAMS
 *  lpTable [I] Pointer to the HANDLETABLE structure, which is to be initalized.
 *
 * NOTES
 *  Note that alloc_handle_table calls init_handle_table on it's own, which 
 *  means that you only have to call init_handle_table, if you use a global
 *  variable of type HANDLETABLE for your handle table. However, in this
 *  case you have to call destroy_handle_table when you don't need the table
 *  any more.
 */
void init_handle_table(HANDLETABLE *lpTable)
{
    TRACE("(lpTable=%p)\n", lpTable);
        
    lpTable->paEntries = NULL;
    lpTable->iEntries = 0;
    lpTable->iFirstFree = 0;
    InitializeCriticalSection(&lpTable->mutex);
}

/******************************************************************************
 *  destroy_handle_table
 *
 * Destroys the handle table.
 * 
 * PARAMS
 *  lpTable [I] Pointer to the handle table, which is to be destroyed.
 *
 * NOTES
 *  Note that release_handle_table takes care of this.
 */
void destroy_handle_table(HANDLETABLE *lpTable)
{
    TRACE("(lpTable=%p)\n", lpTable);
        
    if (lpTable->paEntries) 
        HeapFree(GetProcessHeap(), 0, lpTable->paEntries);
    DeleteCriticalSection(&lpTable->mutex);
}

/******************************************************************************
 *  is_valid_handle
 *
 * Tests if handle is valid given the specified handle table
 * 
 * PARAMS
 *  lpTable [I] Pointer to the handle table, with respect to which the handle's 
 *              validness is tested.
 *  handle  [I] The handle tested for validness.
 *  dwType  [I] A magic value that identifies the referenced object's type.
 *
 * RETURNS
 *  non zero,  if handle is valid.
 *  zero,      if handle is not valid.
 */
int is_valid_handle(HANDLETABLE *lpTable, unsigned int handle, DWORD dwType)
{
    unsigned int index = HANDLE2INDEX(handle);
    int ret = 0;

    TRACE("(lpTable=%p, handle=%d)\n", lpTable, handle);
    
    EnterCriticalSection(&lpTable->mutex);
        
    /* We don't use zero handle values */
    if (!handle) goto exit;
 
    /* Check for index out of table bounds */    
    if (index >= lpTable->iEntries) goto exit;
    
    /* Check if this handle is currently allocated */
    if (!lpTable->paEntries[index].pObject) goto exit;
    
    /* Check if this handle references an object of the correct type. */
    if (lpTable->paEntries[index].pObject->dwType != dwType) goto exit;
    
    ret = 1;
exit:
    LeaveCriticalSection(&lpTable->mutex);
    return ret;
}

/******************************************************************************
 *  alloc_handle_table
 *
 * Allocates a new handle table
 * 
 * PARAMS
 *  lplpTable [O] Pointer to the variable, to which the pointer to the newly
 *                allocated handle table is written.
 * RETURNS
 *  non zero,  if successfull
 *  zero,      if not successfull (out of process heap memory)
 *
 * NOTES
 *  If all you need is a single handle table, you may as well declare a global 
 *  variable of type HANDLETABLE and call init_handle_table on your own. 
 */
int alloc_handle_table(HANDLETABLE **lplpTable)
{
    TRACE("(lplpTable=%p)\n", lplpTable);
        
    *lplpTable = HeapAlloc(GetProcessHeap(), 0, sizeof(HANDLETABLE));
    if (*lplpTable) 
    {
        init_handle_table(*lplpTable);
        return 1;
    }
    else
        return 0;
}

/******************************************************************************
 *  release_handle_table
 *
 * Releases a handle table and frees the resources occupied by it.
 *
 * PARAMS
 *  lpTable [I] Pointer to the handle table, which is to be released.
 *
 * RETURNS
 *  non zero,  if successfull
 *  zero,      if not successfull
 *
 * NOTES
 *   All valid handles still in the table are released also.
 */
int release_handle_table(HANDLETABLE *lpTable) 
{
    TRACE("(lpTable=%p)\n", lpTable);
        
    release_all_handles(lpTable);
    destroy_handle_table(lpTable);
    return (int)HeapFree(GetProcessHeap(), 0, lpTable);
}

/******************************************************************************
 *  grow_handle_table [Internal]
 *
 * Grows the number of entries in the given table by TABLE_SIZE_INCREMENT
 *
 * PARAMS 
 *  lpTable [I] Pointer to the table, which is to be grown
 *
 * RETURNS
 *  non zero,  if successfull
 *  zero,      if not successfull (out of memory on process heap)
 *
 * NOTES
 *  This is a support function for alloc_handle. Do not call!
 */
static int grow_handle_table(HANDLETABLE *lpTable) 
{
    HANDLETABLEENTRY *newEntries;
    unsigned int i, newIEntries;

    newIEntries = lpTable->iEntries + TABLE_SIZE_INCREMENT;

    newEntries = (HANDLETABLEENTRY*)HeapAlloc(GetProcessHeap(), 0, 
                                              sizeof(HANDLETABLEENTRY)*newIEntries);
    if (!newEntries) 
        return 0;

    if (lpTable->paEntries)
    {
        memcpy(newEntries, lpTable->paEntries, sizeof(HANDLETABLEENTRY)*lpTable->iEntries);
        HeapFree(GetProcessHeap(), 0, lpTable->paEntries);
    }

    for (i=lpTable->iEntries; i<newIEntries; i++)
    {
        newEntries[i].pObject = NULL;
        newEntries[i].iNextFree = i+1;
    }

    lpTable->paEntries = newEntries;
    lpTable->iEntries = newIEntries;

    return 1;
}

/******************************************************************************
 *  alloc_handle
 *
 * Allocates a new handle to the specified object in a given handle table.
 *
 * PARAMS
 *  lpTable  [I] Pointer to the handle table, from which the new handle is 
 *               allocated.
 *  lpObject [I] Pointer to the object, for which a handle shall be allocated.
 *  lpHandle [O] Pointer to a handle variable, into which the handle value will
 *               be stored. If not successfull, this will be 
 *               INVALID_HANDLE_VALUE
 * RETURNS
 *  non zero,  if successfull
 *  zero,      if not successfull (no free handle)
 */
int alloc_handle(HANDLETABLE *lpTable, OBJECTHDR *lpObject, unsigned int *lpHandle)
{
    int ret = 0;
        
    TRACE("(lpTable=%p, lpObject=%p, lpHandle=%p)\n", lpTable, lpObject, lpHandle);
        
    EnterCriticalSection(&lpTable->mutex);
    if (lpTable->iFirstFree >= lpTable->iEntries) 
        if (!grow_handle_table(lpTable))
        {
            *lpHandle = (unsigned int)INVALID_HANDLE_VALUE;
            goto exit;
        }

    *lpHandle = INDEX2HANDLE(lpTable->iFirstFree);
    
    lpTable->paEntries[lpTable->iFirstFree].pObject = lpObject;
    lpTable->iFirstFree = lpTable->paEntries[lpTable->iFirstFree].iNextFree;
    lpObject->refcount++;

    ret = 1;
exit:
    LeaveCriticalSection(&lpTable->mutex);
    return ret;
}

/******************************************************************************
 *  release_handle
 *
 * Releases resources occupied by the specified handle in the given table.
 * The reference count of the handled object is decremented. If it becomes
 * zero and if the 'destructor' function pointer member is non NULL, the
 * destructor function will be called. Note that release_handle does not 
 * release resources other than the handle itself. If this is wanted, do it
 * in the destructor function.
 *
 * PARAMS
 *  lpTable [I] Pointer to the handle table, from which a handle is to be 
 *              released.
 *  handle  [I] The handle, which is to be released
 *  dwType  [I] Identifier for the type of the object, for which a handle is
 *              to be released.
 *
 * RETURNS
 *  non zero,  if successfull
 *  zero,      if not successfull (invalid handle)
 */
int release_handle(HANDLETABLE *lpTable, unsigned int handle, DWORD dwType)
{
    unsigned int index = HANDLE2INDEX(handle);
    OBJECTHDR *pObject;
    int ret = 0;

    TRACE("(lpTable=%p, hande=%d)\n", lpTable, handle);
    
    EnterCriticalSection(&lpTable->mutex);
    
    if (!is_valid_handle(lpTable, handle, dwType))
        goto exit;

    pObject = lpTable->paEntries[index].pObject;
    pObject->refcount--;
    if (pObject->refcount == 0)
        if (pObject->destructor)
            pObject->destructor(pObject);

    lpTable->paEntries[index].pObject = NULL;
    lpTable->paEntries[index].iNextFree = lpTable->iFirstFree;
    lpTable->iFirstFree = index;
   
    ret = 1;
exit:
    LeaveCriticalSection(&lpTable->mutex);
    return ret;
}

/******************************************************************************
 *  release_all_handles
 *
 * Releases all valid handles in the given handle table and shrinks the table 
 * to zero size.
 *
 * PARAMS
 *  lpTable [I] The table of which all valid handles shall be released.
 */
void release_all_handles(HANDLETABLE *lpTable) 
{
    unsigned int i;

    TRACE("(lpTable=%p)\n", lpTable);
        
    EnterCriticalSection(&lpTable->mutex);
    for (i=0; i<lpTable->iEntries; i++) 
        if (lpTable->paEntries[i].pObject)
            release_handle(lpTable, lpTable->paEntries[i].pObject->dwType, INDEX2HANDLE(i));
    LeaveCriticalSection(&lpTable->mutex);
}

/******************************************************************************
 *  lookup_handle
 *
 * Returns the object identified by the handle in the given handle table
 *
 * PARAMS
 *  lpTable    [I] Pointer to the handle table, in which the handle is looked up.
 *  handle     [I] The handle, which is to be looked up
 *    lplpObject [O] Pointer to the variable, into which the pointer to the 
 *                   object looked up is copied.
 * RETURNS
 *  non zero,  if successfull
 *  zero,      if not successfull (invalid handle)
 */
int lookup_handle(HANDLETABLE *lpTable, unsigned int handle, DWORD dwType, OBJECTHDR **lplpObject)
{
    int ret = 0;
    
    TRACE("(lpTable=%p, handle=%d, lplpObject=%p)\n", lpTable, handle, lplpObject);
    
    EnterCriticalSection(&lpTable->mutex);
    if (!is_valid_handle(lpTable, handle, dwType)) 
    {
        *lplpObject = NULL;
        goto exit;
    }
    *lplpObject = lpTable->paEntries[HANDLE2INDEX(handle)].pObject;

    ret = 1;
exit:
    LeaveCriticalSection(&lpTable->mutex);
    return ret;
}

/******************************************************************************
 *  copy_handle
 *
 * Copies a handle. Increments reference count in the object referenced by the
 * handle
 *
 * PARAMS
 *  lpTable [I] Pointer to the handle table, which holds the handle to be copied.
 *  handle  [I] The handle to be copied.
 *  copy    [O] Pointer to a handle variable, where the copied handle is put.
 *
 * RETURNS
 *  non zero,  if successfull
 *  zero,      if not successfull (invalid handle or out of memory)
 */
int copy_handle(HANDLETABLE *lpTable, unsigned int handle, DWORD dwType, unsigned int *copy)
{
    OBJECTHDR *pObject;
    int ret;
        
    TRACE("(lpTable=%p, handle=%d, copy=%p)\n", lpTable, handle, copy);

    EnterCriticalSection(&lpTable->mutex);
    if (!lookup_handle(lpTable, handle, dwType, &pObject)) 
    {
        *copy = (unsigned int)INVALID_HANDLE_VALUE;
        LeaveCriticalSection(&lpTable->mutex);
        return 0;
    }

    ret = alloc_handle(lpTable, pObject, copy);
    LeaveCriticalSection(&lpTable->mutex);
    return ret;
}

/******************************************************************************
 *  new_object
 *
 * Allocates a new object of size cbSize on the current process's heap.
 * Initializes the object header using the destructor and dwType params.
 * Allocates a handle to the object in the handle table pointed to by lpTable.
 * Returns a pointer to the created object in ppObject.
 * Returns a handle to the created object.
 *
 * PARAMS
 *  lpTable    [I] Pointer to the handle table, from which a handle is to be 
 *              allocated.
 *  cbSize     [I] Size of the object to be allocated in bytes.
 *  dwType     [I] Object type; will be copied to the object header.
 *  destructor [I] Function pointer to a destructor function. Will be called
 *                 once the object's reference count gets zero.
 *  ppObject   [O] Pointer to a pointer variable, where a pointer to the newly
 *                 created object will be stored. You may set this to NULL.
 *
 * RETURNS
 *  INVALID_HANDLE_VALUE,        if something went wrong.
 *  a handle to the new object,  if successfull. 
 */
unsigned int new_object(HANDLETABLE *lpTable, size_t cbSize, DWORD dwType, DESTRUCTOR destructor, 
                        OBJECTHDR **ppObject)
{
    OBJECTHDR *pObject;
    unsigned int hObject;

    if (ppObject)
        *ppObject = NULL;

    pObject = (OBJECTHDR*)HeapAlloc(GetProcessHeap(), 0, cbSize);
    if (!pObject)
        return (unsigned int)INVALID_HANDLE_VALUE;

    pObject->dwType = dwType;
    pObject->refcount = 0;
    pObject->destructor = destructor;

    if (!alloc_handle(lpTable, pObject, &hObject))
        HeapFree(GetProcessHeap(), 0, pObject);
    else
        if (ppObject)
            *ppObject = pObject;

    return hObject;
}
