/*
 * KERNEL32 objects
 *
 * Copyright 1996 Alexandre Julliard
 */

#include <assert.h>
#include "winerror.h"
#include "handle32.h"
#include "heap.h"
#include "file.h"
#include "process.h"
#include "thread.h"

typedef void (*destroy_object)(K32OBJ *);

extern void VIRTUAL_DestroyMapping( K32OBJ *obj );

static const destroy_object K32OBJ_Destroy[K32OBJ_NBOBJECTS] =
{
    NULL,
    NULL,                     /* K32OBJ_SEMAPHORE */
    NULL,                     /* K32OBJ_EVENT */
    NULL,                     /* K32OBJ_MUTEX */
    NULL,                     /* K32OBJ_CRITICAL_SECTION */
    PROCESS_Destroy,          /* K32OBJ_PROCESS */
    THREAD_Destroy,           /* K32OBJ_THREAD */
    FILE_Destroy,             /* K32OBJ_FILE */
    NULL,                     /* K32OBJ_CHANGE */
    NULL,                     /* K32OBJ_CONSOLE */
    NULL,                     /* K32OBJ_SCREEN_BUFFER */
    VIRTUAL_DestroyMapping,   /* K32OBJ_MEM_MAPPED_FILE */
    NULL,                     /* K32OBJ_SERIAL */
    NULL,                     /* K32OBJ_DEVICE_IOCTL */
    NULL,                     /* K32OBJ_PIPE */
    NULL,                     /* K32OBJ_MAILSLOT */
    NULL,                     /* K32OBJ_TOOLHELP_SNAPSHOT */
    NULL                      /* K32OBJ_SOCKET */
};

typedef struct _NE
{
    struct _NE *next;
    K32OBJ     *obj;
    UINT32      len;
    char        name[1];
} NAME_ENTRY;

static NAME_ENTRY *K32OBJ_FirstEntry = NULL;


/***********************************************************************
 *           K32OBJ_IncCount
 */
void K32OBJ_IncCount( K32OBJ *ptr )
{
    /* FIXME: not atomic */
    assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) );
    ptr->refcount++;
}


/***********************************************************************
 *           K32OBJ_DecCount
 */
void K32OBJ_DecCount( K32OBJ *ptr )
{
    NAME_ENTRY **pptr;

    /* FIXME: not atomic */
    assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) );
    assert( ptr->refcount );
    if (--ptr->refcount) return;

    /* Check if the object has a name entry and free it */

    pptr = &K32OBJ_FirstEntry;
    while (*pptr && ((*pptr)->obj != ptr)) pptr = &(*pptr)->next;
    if (*pptr)
    {
        NAME_ENTRY *entry = *pptr;
        *pptr = entry->next;
        HeapFree( SystemHeap, 0, entry );
    }

    /* Free the object */

    if (K32OBJ_Destroy[ptr->type]) K32OBJ_Destroy[ptr->type]( ptr );
}


/***********************************************************************
 *           K32OBJ_AddName
 *
 * Add a name entry for an object. We don't check for duplicates here.
 * FIXME: should use some sort of hashing.
 */
BOOL32 K32OBJ_AddName( K32OBJ *obj, LPCSTR name )
{
    NAME_ENTRY *entry = K32OBJ_FirstEntry;
    UINT32 len = strlen( name );

    if (!(entry = HeapAlloc( SystemHeap, 0, sizeof(entry) + len )))
    {
        SetLastError( ERROR_OUTOFMEMORY );
        return FALSE;
    }
    entry->next = K32OBJ_FirstEntry;
    entry->obj = obj;
    lstrcpy32A( entry->name, name );
    K32OBJ_FirstEntry = entry;
    return TRUE;
}


/***********************************************************************
 *           K32OBJ_FindName
 *
 * Find the object referenced by a given name.
 * The reference count is not incremented.
 */
K32OBJ *K32OBJ_FindName( LPCSTR name )
{
    NAME_ENTRY *entry = K32OBJ_FirstEntry;
    UINT32 len;

    if (!name) return NULL;  /* Anonymous object */
    len = strlen( name );
    while (entry)
    {
        if ((len == entry->len) && !lstrcmp32A( name, entry->name))
            return entry->obj;
        entry = entry->next;
    }
    return NULL;
}


/***********************************************************************
 *           K32OBJ_FindNameType
 *
 * Find an object by name and check its type.
 * The reference count is not incremented.
 */
K32OBJ *K32OBJ_FindNameType( LPCSTR name, K32OBJ_TYPE type )
{
    K32OBJ *obj = K32OBJ_FindName( name );
    if (!obj) return NULL;
    if (obj->type == type) return obj;
    SetLastError( ERROR_DUP_NAME );
    return NULL;
}
