/*
 * 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, SECURITY_ATTRIBUTES *sa, HANDLE32 *handle)
{
    BOOL32 inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);

    /* Check if the name already exists */

    K32OBJ *obj = K32OBJ_FindName( name );
    if (obj)
    {
        if (obj->type == type)
        {
            SetLastError( ERROR_ALREADY_EXISTS );
            *handle = HANDLE_Alloc( PROCESS_Current(), obj, access, inherit );
        }
        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( PROCESS_Current(), obj, access, inherit );
    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) && !strcmp( 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;
}
