/*
 * Atom table functions
 *
 * Copyright 1993, 1994, 1995 Alexandre Julliard
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winternl.h"

#include "wine/exception.h"
#include "wine/unicode.h"
#include "kernel_private.h"

#define MAX_ATOM_LEN 255
#define IS_INTATOM(x)   (((ULONG_PTR)(x) >> 16) == 0)

/******************************************************************
 *		get_local_table
 *
 * Returns the local atom table for this process (and create it if doesn't
 * exist yet)
 */
static RTL_ATOM_TABLE get_local_table(DWORD entries)
{
    static RTL_ATOM_TABLE local_table;

    if (!local_table)
    {
        NTSTATUS        status;
        RTL_ATOM_TABLE  table = NULL;

        if ((status = RtlCreateAtomTable( entries, &table )))
            SetLastError( RtlNtStatusToDosError( status ) );
        else if (InterlockedCompareExchangePointer((void*)&local_table, table, NULL) != NULL)
            RtlDestroyAtomTable( table );
    }

    return local_table;
}


/***********************************************************************
 *           InitAtomTable   (KERNEL32.@)
 *
 * Initialise the global atom table.
 *
 * PARAMS
 *  entries [I] The number of entries to reserve in the table.
 *
 * RETURNS
 *  Success: TRUE.
 *  Failure: FALSE.
 */
BOOL WINAPI InitAtomTable( DWORD entries )
{
    return get_local_table( entries ) != 0;
}

/******************************************************************
 *		check_integral_atom
 *
 * Check if a string (ANSI or UNICODE) is in fact an integral atom
 * (but doesn't check the "#1234" form)
 */
static inline BOOL check_integral_atom( const void* ptr, ATOM* patom)
{
    if (!IS_INTATOM( ptr )) return FALSE;
    if ((*patom = LOWORD( ptr )) >= MAXINTATOM)
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        *patom = 0;
    }
    return TRUE;
}

/***********************************************************************
 *           GlobalAddAtomA   (KERNEL32.@)
 *
 * Add a character string to the global atom table and return a unique
 * value identifying it.
 *
 * RETURNS
 *	Success: The atom allocated to str.
 *	Failure: 0.
 */
ATOM WINAPI GlobalAddAtomA( LPCSTR str /* [in] String to add */ )
{
    ATOM atom = 0;
    __TRY
    {
        if (!check_integral_atom( str, &atom ))
	{
	    WCHAR buffer[MAX_ATOM_LEN];
	    DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), buffer, MAX_ATOM_LEN );
	    if (!len) SetLastError( ERROR_INVALID_PARAMETER );
	    else
	    {
	        NTSTATUS status = NtAddAtom( buffer, len * sizeof(WCHAR), &atom );
		if (status)
		{
		    SetLastError( RtlNtStatusToDosError( status ) );
		    atom = 0;
		}
	    }
	}
    }
    __EXCEPT_PAGE_FAULT
    {
        SetLastError( ERROR_INVALID_PARAMETER );
        atom = 0;
    }
    __ENDTRY
    return atom;
}


/***********************************************************************
 *           AddAtomA   (KERNEL32.@)
 *
 * Add a character string to the global atom table and return a unique
 * value identifying it.
 *
 * RETURNS
 *      Success: The atom allocated to str.
 *      Failure: 0.
 */
ATOM WINAPI AddAtomA( LPCSTR str /* [in] String to add */ )
{
    ATOM atom = 0;

    if (!check_integral_atom( str, &atom ))
    {
        WCHAR           buffer[MAX_ATOM_LEN + 1];
        DWORD           len;
        RTL_ATOM_TABLE  table;

        len = MultiByteToWideChar( CP_ACP, 0, str, -1, buffer, MAX_ATOM_LEN + 1 );
        if (!len) SetLastError( ERROR_INVALID_PARAMETER );
        else if ((table = get_local_table( 0 )))
        {
            NTSTATUS status = RtlAddAtomToAtomTable( table, buffer, &atom );
            if (status)
            {
                SetLastError( RtlNtStatusToDosError( status ) );
                atom = 0;
            }
        }
    }
    return atom;
}

/***********************************************************************
 *           GlobalAddAtomW   (KERNEL32.@)
 *
 * Unicode version of GlobalAddAtomA.
 */
ATOM WINAPI GlobalAddAtomW( LPCWSTR str )
{
    ATOM        atom = 0;
    NTSTATUS    status;

    if (!check_integral_atom( str, &atom ) && 
        (status = NtAddAtom( str, strlenW( str ) * sizeof(WCHAR), &atom )))
    {
        SetLastError( RtlNtStatusToDosError( status ) );
        atom = 0;
    }
    return atom;
}


/***********************************************************************
 *           AddAtomW   (KERNEL32.@)
 *
 * Unicode version of AddAtomA.          
 */
ATOM WINAPI AddAtomW( LPCWSTR str )
{
    ATOM                atom = 0;
    RTL_ATOM_TABLE      table;

    if (!check_integral_atom( str, &atom ) && (table = get_local_table( 0 )))
    {
        NTSTATUS status = RtlAddAtomToAtomTable( table, str, &atom );
        if (status)
        {
            SetLastError( RtlNtStatusToDosError( status ) );
            atom = 0;
        }
    }
    return atom;
}


/***********************************************************************
 *           GlobalDeleteAtom   (KERNEL32.@)
 *
 * Decrement the reference count of a string atom.  If the count is
 * zero, the string associated with the atom is removed from the table.
 *
 * RETURNS
 *	Success: 0.
 *	Failure: atom.
 */
ATOM WINAPI GlobalDeleteAtom( ATOM atom /* [in] Atom to delete */ )
{
    if (atom >= MAXINTATOM)
    {
        NTSTATUS status = NtDeleteAtom( atom );
        if (status)
        {
            SetLastError( RtlNtStatusToDosError( status ) );
            return atom;
        }
    }
    return 0;
}


/***********************************************************************
 *           DeleteAtom   (KERNEL32.@)
 *
 * Decrement the reference count of a string atom.  If the count becomes
 * zero, the string associated with the atom is removed from the table.
 *
 * RETURNS
 *	Success: 0.
 *	Failure: atom
 */
ATOM WINAPI DeleteAtom( ATOM atom /* [in] Atom to delete */ )
{
    NTSTATUS            status;
    RTL_ATOM_TABLE      table;

    if (atom >= MAXINTATOM)
    {
        if (!(table = get_local_table( 0 ))) return atom;
        status = RtlDeleteAtomFromAtomTable( table, atom );
        if (status)
        {
            SetLastError( RtlNtStatusToDosError( status ) );
            return atom;
        }
    }
    return 0;
}


/***********************************************************************
 *           GlobalFindAtomA   (KERNEL32.@)
 *
 * Get the atom associated with a string.
 *
 * RETURNS
 *	Success: The associated atom.
 *	Failure: 0.
 */
ATOM WINAPI GlobalFindAtomA( LPCSTR str /* [in] Pointer to string to search for */ )
{
    ATOM atom = 0;

    if (!check_integral_atom( str, &atom ))
    {
        WCHAR buffer[MAX_ATOM_LEN];
        DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), buffer, MAX_ATOM_LEN );

        if (!len) SetLastError( ERROR_INVALID_PARAMETER );
        else
        {
            NTSTATUS status = NtFindAtom( buffer, len * sizeof(WCHAR), &atom );
            if (status)
            {
                SetLastError( RtlNtStatusToDosError( status ) );
                atom = 0;
            }
        }
    }
    return atom;
}

/***********************************************************************
 *           FindAtomA   (KERNEL32.@)
 *
 * Get the atom associated with a string.
 *
 * RETURNS
 *	Success: The associated atom.
 *	Failure: 0.
 */
ATOM WINAPI FindAtomA( LPCSTR str /* [in] Pointer to string to find */ )
{
    ATOM atom = 0;

    if (!check_integral_atom( str, &atom ))
    {
        WCHAR           buffer[MAX_ATOM_LEN + 1];
        DWORD           len;
        RTL_ATOM_TABLE  table;

        len = MultiByteToWideChar( CP_ACP, 0, str, -1, buffer, MAX_ATOM_LEN + 1 );
        if (!len) SetLastError( ERROR_INVALID_PARAMETER );
        else if ((table = get_local_table( 0 )))
        {
            NTSTATUS status = RtlLookupAtomInAtomTable( table, buffer, &atom );
            if (status)
            {
                SetLastError( RtlNtStatusToDosError( status ) );
                atom = 0;
            }
        }
    }
    return atom;
}


/***********************************************************************
 *           GlobalFindAtomW   (KERNEL32.@)
 *
 * Unicode version of GlobalFindAtomA.
 */
ATOM WINAPI GlobalFindAtomW( LPCWSTR str )
{
    ATOM atom = 0;

    if (!check_integral_atom( str, &atom ))
    {
        NTSTATUS status = NtFindAtom( str, strlenW( str ) * sizeof(WCHAR), &atom );
        if (status)
        {
            SetLastError( RtlNtStatusToDosError( status ) );
            atom = 0;
        }
    }
    return atom;
}


/***********************************************************************
 *           FindAtomW   (KERNEL32.@)
 *
 * Unicode version of FindAtomA.
 */
ATOM WINAPI FindAtomW( LPCWSTR str )
{
    ATOM                atom = 0;
    NTSTATUS            status;
    RTL_ATOM_TABLE      table;

    if ((table = get_local_table( 0 )))
    {
        status = RtlLookupAtomInAtomTable( table, str, &atom );
        if (status)
        {
            SetLastError( RtlNtStatusToDosError( status ) );
            atom = 0;
        }
    }
    return atom;
}


/***********************************************************************
 *           GlobalGetAtomNameA   (KERNEL32.@)
 *
 * Get a copy of the string associated with an atom.
 *
 * RETURNS
 *	Success: The length of the returned string in characters.
 *	Failure: 0.
 */
UINT WINAPI GlobalGetAtomNameA(
              ATOM atom,    /* [in]  Atom identifier */
              LPSTR buffer, /* [out] Pointer to buffer for atom string */
              INT count )   /* [in]  Size of buffer */
{
    WCHAR       tmpW[MAX_ATOM_LEN + 1];
    UINT        wlen, len = 0, c;

    if (count <= 0) SetLastError( ERROR_MORE_DATA );
    else if ((wlen = GlobalGetAtomNameW( atom, tmpW, MAX_ATOM_LEN + 1 )))
    {
        char    tmp[MAX_ATOM_LEN + 1];

        len = WideCharToMultiByte( CP_ACP, 0, tmpW, wlen, tmp, MAX_ATOM_LEN + 1, NULL, NULL );
        c = min(len, count - 1);
        memcpy(buffer, tmp, c);
        buffer[c] = '\0';
        if (len >= count)
        {
            len = 0;
            SetLastError( ERROR_MORE_DATA );
        }
    }
    return len;
}


/***********************************************************************
 *           GetAtomNameA   (KERNEL32.@)
 *
 * Get a copy of the string associated with an atom.
 *
 * RETURNS
 *	Success: The length of the returned string in characters.
 *	Failure: 0.
 */
UINT WINAPI GetAtomNameA(
              ATOM atom,    /* [in]  Atom */
              LPSTR buffer, /* [out] Pointer to string for atom string */
              INT count)    /* [in]  Size of buffer */
{
    WCHAR       tmpW[MAX_ATOM_LEN + 1];
    UINT        wlen, len = 0, c;

    if (count <= 0) SetLastError( ERROR_MORE_DATA );
    else if ((wlen = GetAtomNameW( atom, tmpW, MAX_ATOM_LEN + 1 )))
    {
        char    tmp[MAX_ATOM_LEN + 1];

        len = WideCharToMultiByte( CP_ACP, 0, tmpW, wlen, tmp, MAX_ATOM_LEN + 1, NULL, NULL );
        c = min(len, count - 1);
        memcpy(buffer, tmp, c);
        buffer[c] = '\0';
        if (len >= count)
        {
            len = c;
            SetLastError( ERROR_MORE_DATA );
        }
    }
    return len;
}


/***********************************************************************
 *           GlobalGetAtomNameW   (KERNEL32.@)
 *
 * Unicode version of GlobalGetAtomNameA.
 */
UINT WINAPI GlobalGetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
{
    char        ptr[sizeof(ATOM_BASIC_INFORMATION) + MAX_ATOM_LEN * sizeof(WCHAR)];
    ATOM_BASIC_INFORMATION*     abi = (ATOM_BASIC_INFORMATION*)ptr;
    ULONG       ptr_size = sizeof(ATOM_BASIC_INFORMATION) + MAX_ATOM_LEN * sizeof(WCHAR);
    NTSTATUS    status;
    UINT        length = 0;

    if (count <= 0)
    {
        SetLastError( ERROR_MORE_DATA );
        return 0;
    }
    status = NtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
    if (status) SetLastError( RtlNtStatusToDosError( status ) );
    else
    {
        length = min( abi->NameLength / sizeof(WCHAR), count);
        memcpy( buffer, abi->Name, length * sizeof(WCHAR) );
        /* yes, the string will not be null terminated if the passed buffer
         * is one WCHAR too small (and it's not an error)
         */
        if (length < abi->NameLength / sizeof(WCHAR))
        {
            SetLastError( ERROR_MORE_DATA );
            length = count;
        }
        else if (length < count) buffer[length] = '\0';
    }
    return length;
}


/***********************************************************************
 *           GetAtomNameW   (KERNEL32.@)
 *
 * Unicode version of GetAtomNameA.
 */
UINT WINAPI GetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
{
    NTSTATUS            status;
    RTL_ATOM_TABLE      table;
    DWORD               length;
    WCHAR               tmp[MAX_ATOM_LEN + 1];

    if (count <= 0)
    {
        SetLastError( ERROR_MORE_DATA );
        return 0;
    }
    if (!(table = get_local_table( 0 ))) return 0;
    length = sizeof(tmp);
    status = RtlQueryAtomInAtomTable( table, atom, NULL, NULL, tmp, &length );
    if (status)
    {
        SetLastError( RtlNtStatusToDosError( status ) );
        return 0;
    }
    length = min(length, (count - 1) * sizeof(WCHAR));
    if (length) memcpy(buffer, tmp, length);
    else SetLastError( ERROR_INSUFFICIENT_BUFFER );
    length /= sizeof(WCHAR);
    buffer[length] = '\0';
    return length;
}
