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

#include <assert.h>
#include "winerror.h"
#include "k32obj.h"
#include "heap.h"
#include "process.h"


/* The declarations are here to avoid including a lot of unnecessary files */
extern const K32OBJ_OPS SEMAPHORE_Ops;
extern const K32OBJ_OPS EVENT_Ops;
extern const K32OBJ_OPS MUTEX_Ops;
extern const K32OBJ_OPS CRITICAL_SECTION_Ops;
extern const K32OBJ_OPS PROCESS_Ops;
extern const K32OBJ_OPS THREAD_Ops;
extern const K32OBJ_OPS FILE_Ops;
extern const K32OBJ_OPS MEM_MAPPED_FILE_Ops;
extern const K32OBJ_OPS CONSOLE_Ops;

static const K32OBJ_OPS K32OBJ_NullOps =
{
    NULL,    /* signaled */
    NULL,    /* satisfied */
    NULL,    /* add_wait */
    NULL,    /* remove_wait */
    NULL,    /* read */
    NULL,    /* write */
    NULL     /* destroy */
};

const K32OBJ_OPS * const K32OBJ_Ops[K32OBJ_NBOBJECTS] =
{
    NULL,
    &SEMAPHORE_Ops,         /* K32OBJ_SEMAPHORE */
    &EVENT_Ops,             /* K32OBJ_EVENT */
    &MUTEX_Ops,             /* K32OBJ_MUTEX */
    &CRITICAL_SECTION_Ops,  /* K32OBJ_CRITICAL_SECTION */
    &PROCESS_Ops,           /* K32OBJ_PROCESS */
    &THREAD_Ops,            /* K32OBJ_THREAD */
    &FILE_Ops,              /* K32OBJ_FILE */
    &K32OBJ_NullOps,        /* K32OBJ_CHANGE */
    &CONSOLE_Ops,           /* K32OBJ_CONSOLE */
    &K32OBJ_NullOps,        /* K32OBJ_SCREEN_BUFFER */
    &MEM_MAPPED_FILE_Ops,   /* K32OBJ_MEM_MAPPED_FILE */
    &K32OBJ_NullOps,        /* K32OBJ_SERIAL */
    &K32OBJ_NullOps,        /* K32OBJ_DEVICE_IOCTL */
    &K32OBJ_NullOps,        /* K32OBJ_PIPE */
    &K32OBJ_NullOps,        /* K32OBJ_MAILSLOT */
    &K32OBJ_NullOps,        /* K32OBJ_TOOLHELP_SNAPSHOT */
    &K32OBJ_NullOps         /* 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 )
{
    assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) );
    SYSTEM_LOCK();
    ptr->refcount++;
    SYSTEM_UNLOCK();
    assert( ptr->refcount > 0 );  /* No wrap-around allowed */
}


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

    assert( ptr->type && ((unsigned)ptr->type < K32OBJ_NBOBJECTS) );
    assert( ptr->refcount > 0 );
    SYSTEM_LOCK();
    if (--ptr->refcount)
    {
        SYSTEM_UNLOCK();
        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_Ops[ptr->type]->destroy) K32OBJ_Ops[ptr->type]->destroy( ptr );
    SYSTEM_UNLOCK();
}


/***********************************************************************
 *           K32OBJ_IsValid
 *
 * Check if a pointer is a valid kernel object
 */
BOOL32 K32OBJ_IsValid( K32OBJ *ptr, K32OBJ_TYPE type )
{
    if (IsBadReadPtr32( ptr, sizeof(*ptr) )) return FALSE;
    return (ptr->type == type);
}


/***********************************************************************
 *           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;
    UINT32 len;

    if (!name) return TRUE;  /* Anonymous object */
    len = strlen( name );
    SYSTEM_LOCK();
    if (!(entry = HeapAlloc( SystemHeap, 0, sizeof(NAME_ENTRY) + len )))
    {
        SYSTEM_UNLOCK();
        SetLastError( ERROR_OUTOFMEMORY );
        return FALSE;
    }
    entry->next = K32OBJ_FirstEntry;
    entry->obj = obj;
    lstrcpy32A( entry->name, name );
    K32OBJ_FirstEntry = entry;
    SYSTEM_UNLOCK();
    return TRUE;
}


/***********************************************************************
 *           K32OBJ_Create
 *
 * Create a named kernel object.
 * Returns NULL if there was an error _or_ if the object already existed.
 * The refcount of the object must be decremented once it is initialized.
 */
K32OBJ *K32OBJ_Create( K32OBJ_TYPE type, DWORD size, LPCSTR name,
                       DWORD access, HANDLE32 *handle )
{
    /* Check if the name already exists */

    K32OBJ *obj = K32OBJ_FindName( name );
    if (obj)
    {
        if (obj->type == type)
        {
            SetLastError( ERROR_ALREADY_EXISTS );
            *handle = HANDLE_Alloc( obj, access, FALSE );
        }
        else
        {
            SetLastError( ERROR_DUP_NAME );
            *handle = INVALID_HANDLE_VALUE32;
        }
        K32OBJ_DecCount( obj );
        return NULL;
    }

    /* Create the object */

    SYSTEM_LOCK();
    if (!(obj = HeapAlloc( SystemHeap, 0, size )))
    {
        SYSTEM_UNLOCK();
        *handle = INVALID_HANDLE_VALUE32;
        return NULL;
    }
    obj->type     = type;
    obj->refcount = 1;

    /* Add a name for it */

    if (!K32OBJ_AddName( obj, name ))
    {
        /* Don't call the destroy function, as the object wasn't
         * initialized properly */
        HeapFree( SystemHeap, 0, obj );
        SYSTEM_UNLOCK();
        *handle = INVALID_HANDLE_VALUE32;
        return NULL;
    }

    /* Allocate a handle */

    *handle = HANDLE_Alloc( obj, access, FALSE );
    SYSTEM_UNLOCK();
    return obj;
}


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

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


/***********************************************************************
 *           K32OBJ_FindNameType
 *
 * Find an object by name and check its type.
 * The reference count is 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 );
    K32OBJ_DecCount( obj );
    return NULL;
}
