/*
 * 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);
        
    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 successful
 *  zero,      if not successful (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 it used.
 *
 * PARAMS
 *  lpTable [I] Pointer to the handle table, which is to be released.
 *
 * RETURNS
 *  non zero,  if successful
 *  zero,      if not successful
 *
 * 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 successful
 *  zero,      if not successful (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 = 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 successful, this will be 
 *               INVALID_HANDLE_VALUE
 * RETURNS
 *  non zero,  if successful
 *  zero,      if not successful (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 successful
 *  zero,      if not successful (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 successful
 *  zero,      if not successful (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 the reference count of 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 successful
 *  zero,      if not successful (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 successful. 
 */
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 = 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;
}
