- Dirty temporary fix to unregress abiword/qemu.
[reactos.git] / reactos / lib / kernel32 / misc / atom.c
index c8d9d16..485af4f 100644 (file)
-
-
-#include <Atom.h>
-#include <process.h>
-#include <thread.h>
-#include <wstring.h>
-
-
 /*
-       title:  atom.c
-       author: Boudewijn Dekker
-       hsitory:copied from twin wine source
-       modified:       -- add wide char support
-                       -- removed ex functions
-                       -- use a per process local atom table
-       todo :  
-               check initatomtable
-               check if not calling down to ntdll conflicts with anything
-               check anis2unicode procedure 
-*/
-
-
-/* system global and local atom tables */
-
-static ATOMTABLE GlobalAtomTable;
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS system libraries
+ * FILE:            lib/kernel32/misc/atom.c
+ * PURPOSE:         Atom functions
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ */
 
-/* internal functions */
-ATOM GLDeleteAtom(ATOMTABLE *at, ATOM nAtom);
-ATOM AWGLAddAtom( ATOMTABLE *at, const wchar_t *lpString);
-ATOM AWGLFindAtom(ATOMTABLE *at, const wchar_t *lpString);
-UINT AWGLGetAtomName(ATOMTABLE *at,ATOM atom, wchar_t *lpString, int nSize);
+/* INCLUDES ******************************************************************/
+#include <k32.h>
 
-static ATOMENTRY *GetAtomPointer(ATOMTABLE *,int);
-static ATOMID    AtomHashString(const wchar_t *,int *);
+#define NDEBUG
+#include "../include/debug.h"
 
-#define ATOMBASE        0xcc00
+/* GLOBALS *******************************************************************/
 
+PRTL_ATOM_TABLE BaseLocalAtomTable = NULL;
 
+/* FUNCTIONS *****************************************************************/
 
-ATOM
-STDCALL
-GlobalDeleteAtom(
-    ATOM nAtom
-    )
-{
-       return GLDeleteAtom(&GlobalAtomTable, nAtom);
-}
-
-
-BOOL
-STDCALL
-InitAtomTable(
-    DWORD nSize
-    )
+PVOID
+WINAPI
+InternalInitAtomTable(VOID)
 {
-// nSize should be a prime number
-       
-       if ( nSize < 4 || nSize >= 512 ) {
-               nSize = 37;
-       }
-       /*
-       if ( GetTeb()->pPeb->LocalAtomTable == NULL ) {
-               GetTeb()->pPeb->LocalAtomTable = (ATOMTABLE *)malloc(nSize*sizeof(ATOMTABLE));
-       }
-       
-       GetTeb()->pPeb->LocalAtomTable->TableSize = nSize;
-       */
-       return TRUE;
+    /* Create or return the local table */
+    if (!BaseLocalAtomTable) RtlCreateAtomTable(0, &BaseLocalAtomTable);
+    return BaseLocalAtomTable;
 }
 
-
 ATOM
-STDCALL
-DeleteAtom(
-    ATOM nAtom
-    )
+WINAPI
+InternalAddAtom(BOOLEAN Local,
+                BOOLEAN Unicode,
+                LPCSTR AtomName)
 {
-       return GLDeleteAtom(&GetTeb()->pPeb->LocalAtomTable, nAtom);
-       
+    NTSTATUS Status;
+    ANSI_STRING AnsiString;
+    UNICODE_STRING UnicodeString;
+    PUNICODE_STRING AtomNameString;
+    ATOM Atom = INVALID_ATOM;
+
+    /* Check if it's an integer atom */
+    if ((ULONG_PTR)AtomName <= 0xFFFF)
+    {
+        /* Convert the name to an atom */
+        Atom = (ATOM)PtrToShort((PVOID)AtomName);
+        if (Atom >= MAXINTATOM)
+        {
+            /* Fail, atom number too large */
+            SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
+            return INVALID_ATOM;
+        }
+
+        /* Return it */
+        return Atom;
+    }
+    else
+    {
+        /* Check if this is a unicode atom */
+        if (Unicode)
+        {
+            /* Use a unicode string */
+            AtomNameString = &UnicodeString;
+            RtlInitUnicodeString(AtomNameString, (LPWSTR)AtomName);
+            Status = STATUS_SUCCESS;
+        }
+        else
+        {
+            /* Use an ansi string */
+            RtlInitAnsiString(&AnsiString, AtomName );
+
+            /* Check if we can abuse the TEB */
+            if (AnsiString.MaximumLength > 260)
+            {
+RosHack:
+                /* We can't, allocate a new string */
+                AtomNameString = &UnicodeString;
+                Status = RtlAnsiStringToUnicodeString(AtomNameString,
+                                                      &AnsiString,
+                                                      TRUE);
+            }
+            else
+            {
+                /* We can! Get the TEB String */
+                AtomNameString = &NtCurrentTeb()->StaticUnicodeString;
+
+                /* FIXME: HACK! */
+                if (!AtomNameString->MaximumLength)
+                {
+                    DPRINT1("Hit the ROS TEB Static Unicode String Bug\n",
+                            "Please try to fix the underlying problem!!!\n");
+                    goto RosHack;
+                }
+
+                /* Convert it into the TEB */
+                Status = RtlAnsiStringToUnicodeString(AtomNameString,
+                                                      &AnsiString,
+                                                      FALSE);
+            }
+        }
+
+        /* Check for failure */
+        if (!NT_SUCCESS(Status))
+        {
+            SetLastErrorByStatus(Status);
+            return Atom;
+        }
+    }
+
+    /* Check if we're doing local add */
+    if (Local)
+    {
+        /* Do a local add */
+        Status = RtlAddAtomToAtomTable(InternalInitAtomTable(),
+                                       AtomNameString->Buffer,
+                                       &Atom);
+    }
+    else
+    {
+        /* Do a global add */
+        Status = NtAddAtom(AtomNameString->Buffer,
+                           AtomNameString->Length,
+                           &Atom);
+    }
+
+    /* Check for failure */
+    if (!NT_SUCCESS(Status)) SetLastErrorByStatus(Status);
+
+    /* Check if we were non-static ANSI */
+    if (!(Unicode) && (AtomNameString == &UnicodeString))
+    {
+        /* Free the allocated buffer */
+        RtlFreeUnicodeString(AtomNameString);
+    }
+
+    /* Return the atom */
+    return Atom;
 }
 
-
-
-
 ATOM
-STDCALL
-GlobalAddAtomA(
-    const char *lpString
-    )
+WINAPI
+InternalFindAtom(BOOLEAN Local,
+                 BOOLEAN Unicode,
+                 LPCSTR AtomName)
 {
-
-       UINT     BufLen = strlen(lpString);
-       wchar_t *lpBuffer = (wchar_t *)malloc(BufLen*sizeof(wchar_t));
-       ATOM atom;
-       ansi2unicode(lpBuffer, lpString,BufLen);
-       atom = AWGLAddAtom(&GlobalAtomTable,lpBuffer );
-       free(lpBuffer);
-       return atom;
+    NTSTATUS Status;
+    ANSI_STRING AnsiString;
+    UNICODE_STRING UnicodeString;
+    PUNICODE_STRING AtomNameString;
+    ATOM Atom = INVALID_ATOM;
+
+    /* Check if it's an integer atom */
+    if ((ULONG_PTR)AtomName <= 0xFFFF)
+    {
+        /* Convert the name to an atom */
+        Atom = (ATOM)PtrToShort((PVOID)AtomName);
+        if (Atom >= MAXINTATOM)
+        {
+            /* Fail, atom number too large */
+            SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
+            DPRINT1("Invalid atom\n");
+        }
+
+        /* Return it */
+        return Atom;
+    }
+    else
+    {
+        /* Check if this is a unicode atom */
+        if (Unicode)
+        {
+            /* Use a unicode string */
+            AtomNameString = &UnicodeString;
+            RtlInitUnicodeString(AtomNameString, (LPWSTR)AtomName);
+            Status = STATUS_SUCCESS;
+        }
+        else
+        {
+            /* Use an ansi string */
+            RtlInitAnsiString(&AnsiString, AtomName);
+
+            /* Check if we can abuse the TEB */
+            if (AnsiString.MaximumLength > 260)
+            {
+RosHack:
+                /* We can't, allocate a new string */
+                AtomNameString = &UnicodeString;
+                Status = RtlAnsiStringToUnicodeString(AtomNameString,
+                                                      &AnsiString,
+                                                      TRUE);
+            }
+            else
+            {
+                /* We can! Get the TEB String */
+                AtomNameString = &NtCurrentTeb()->StaticUnicodeString;
+
+                /* FIXME: HACK! */
+                if (!AtomNameString->MaximumLength)
+                {
+                    DPRINT1("Hit the ROS TEB Static Unicode String Bug\n",
+                            "Please try to fix the underlying problem!!!\n");
+                    goto RosHack;
+                }
+
+                /* Convert it into the TEB */
+                Status = RtlAnsiStringToUnicodeString(AtomNameString,
+                                                      &AnsiString,
+                                                      FALSE);
+            }
+        }
+
+        /* Check for failure */
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed\n");
+            SetLastErrorByStatus(Status);
+            return Atom;
+        }
+    }
+
+    /* Check if we're doing local lookup */
+    if (Local)
+    {
+        /* Do a local lookup */
+        Status = RtlLookupAtomInAtomTable(InternalInitAtomTable(),
+                                          AtomNameString->Buffer,
+                                          &Atom);
+    }
+    else
+    {
+        /* Do a global search */
+        if (!AtomNameString->Length)
+        {
+            /* This is illegal in win32 */
+            DPRINT1("No name given\n");
+            Status = STATUS_OBJECT_NAME_NOT_FOUND;
+        }
+        else
+        {
+            /* Call the global function */
+            Status = NtFindAtom(AtomNameString->Buffer,
+                                AtomNameString->Length,
+                                &Atom);
+        }
+    }
+
+    /* Check for failure */
+    if (!NT_SUCCESS(Status)) SetLastErrorByStatus(Status);
+
+    /* Check if we were non-static ANSI */
+    if (!(Unicode) && (AtomNameString == &UnicodeString))
+    {
+        /* Free the allocated buffer */
+        RtlFreeUnicodeString(AtomNameString);
+    }
+
+    /* Return the atom */
+    return Atom;
 }
 
-
-
-
-
 ATOM
-STDCALL
-GlobalAddAtomW(
-    const wchar_t *lpString
-    )
+WINAPI
+InternalDeleteAtom(BOOLEAN Local,
+                   ATOM Atom)
 {
-       return AWGLAddAtom(&GlobalAtomTable, lpString); 
+    NTSTATUS Status;
+
+    /* Validate it */
+    if (Atom >= MAXINTATOM)
+    {
+        /* Check if it's a local delete */
+        if (Local)
+        {
+            /* Delete it locally */
+            Status = RtlDeleteAtomFromAtomTable(InternalInitAtomTable(), Atom);
+        }
+        else
+        {
+            /* Delete it globall */
+            Status = NtDeleteAtom(Atom);
+        }
+
+        /* Check for success */
+        if (!NT_SUCCESS(Status))
+        {
+            /* Fail */
+            SetLastErrorByStatus(Status);
+            return INVALID_ATOM;
+        }
+    }
+
+    /* Return failure */
+    return 0;
 }
 
-
-ATOM
-STDCALL
-GlobalFindAtomA(
-    const char *lpString
-    )
-{
-       ATOM    a;
-       UINT    BufLen = strlen(lpString);
-       wchar_t *lpBuffer = (wchar_t *)malloc(BufLen*sizeof(wchar_t));
-       ansi2unicode(lpBuffer, lpString,BufLen);
-       a = AWGLFindAtom(&GlobalAtomTable, lpBuffer);
-       free(lpBuffer);
-       return a;
-}
-
-
-ATOM
-STDCALL
-GlobalFindAtomW(
-    const wchar_t *lpString
-    )
-{
-       return AWGLFindAtom(&GlobalAtomTable, lpString);        
-}
-
-
-
 UINT
-STDCALL
-GlobalGetAtomNameA(
-    ATOM nAtom,
-    char *lpBuffer,
-    int nSize
-    )
+WINAPI
+InternalGetAtomName(BOOLEAN Local,
+                    BOOLEAN Unicode,
+                    ATOM Atom,
+                    LPSTR AtomName,
+                    DWORD Size)
 {
-       
-       wchar_t *lpUnicode = (wchar_t *)malloc(nSize *sizeof(wchar_t));
-       UINT x = AWGLGetAtomName(&GlobalAtomTable,nAtom, lpUnicode,nSize);      
-       unicode2ansi(lpBuffer,lpUnicode,nSize);
-       free(lpUnicode);
-       return x;
+    NTSTATUS Status;
+    DWORD RetVal = 0;
+    ANSI_STRING AnsiString;
+    UNICODE_STRING UnicodeString;
+    PVOID TempBuffer = NULL;
+    PWSTR AtomNameString;
+    ULONG AtomInfoLength;
+    ULONG AtomNameLength;
+    PATOM_BASIC_INFORMATION AtomInfo;
+
+    /* Normalize the size as not to overflow */
+    if (!Unicode && Size > 0x7000) Size = 0x7000;
+
+    /* Make sure it's valid too */
+    if (!Size)
+    {
+        SetLastErrorByStatus(STATUS_BUFFER_OVERFLOW);
+        return 0;
+    }
+
+    /* Check if this is a global query */
+    if (Local)
+    {
+        /* Set the query length */
+        AtomNameLength = Size * sizeof(WCHAR);
+
+        /* If it's unicode, just keep the name */
+        if (Unicode)
+        {
+            AtomNameString = (PWSTR)AtomName;
+        }
+        else
+        {
+            /* Allocate memory for the ansi buffer */
+            TempBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                         0,
+                                         AtomNameLength);
+            AtomNameString = TempBuffer;
+        }
+
+        /* Query the name */
+        Status = RtlQueryAtomInAtomTable(InternalInitAtomTable(),
+                                         Atom,
+                                         NULL,
+                                         NULL,
+                                         AtomNameString,
+                                         &AtomNameLength);
+    }
+    else
+    {
+        /* We're going to do a global query, so allocate a buffer */
+        AtomInfoLength = sizeof(ATOM_BASIC_INFORMATION) +
+                         (Size * sizeof(WCHAR));
+        AtomInfo = TempBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
+                                                0,
+                                                AtomInfoLength);
+
+        /* Query the name */
+        Status = NtQueryInformationAtom(Atom,
+                                        AtomBasicInformation,
+                                        AtomInfo,
+                                        AtomInfoLength,
+                                        &AtomInfoLength);
+        if (NT_SUCCESS(Status))
+        {
+            /* Success. Update the length and get the name */
+            AtomNameLength = (ULONG)AtomInfo->NameLength;
+            AtomNameString = AtomInfo->Name;
+        }
+    }
+
+    /* Check for global success */
+    if (NT_SUCCESS(Status))
+    {
+        /* Check if it was unicode */
+        if (Unicode)
+        {
+            /* We return the length in chars */
+            RetVal = AtomNameLength / sizeof(WCHAR);
+
+            /* Copy the memory if this was a global query */
+            if (AtomNameString != (PWSTR)AtomName)
+            {
+                RtlMoveMemory(AtomName, AtomNameString, AtomNameLength);
+            }
+
+            /* And null-terminate it if the buffer was too large */
+            if (RetVal < Size)
+            {
+                ((PWCHAR)AtomName)[RetVal] = UNICODE_NULL;
+            }
+        }
+        else
+        {
+            /* First create a unicode string with our data */
+            UnicodeString.Buffer = AtomNameString;
+            UnicodeString.Length = (USHORT)AtomNameLength;
+            UnicodeString.MaximumLength = (USHORT)(UnicodeString.Length +
+                                                   sizeof(WCHAR));
+
+            /* Now prepare an ansi string for conversion */
+            AnsiString.Buffer = AtomName;
+            AnsiString.Length = 0;
+            AnsiString.MaximumLength = (USHORT)Size;
+
+            /* Convert it */
+            Status = RtlUnicodeStringToAnsiString(&AnsiString,
+                                                  &UnicodeString,
+                                                  FALSE);
+
+            /* Return the length */
+            if (NT_SUCCESS(Status)) RetVal = AnsiString.Length;
+        }
+    }
+
+    /* Free the temporary buffer if we have one */
+    if (TempBuffer) RtlFreeHeap(RtlGetProcessHeap(), 0, TempBuffer);
+
+    /* Check for failure */
+    if (!NT_SUCCESS(Status))
+    {
+        /* Fail */
+        DPRINT1("Failed: %lx\n", Status);
+        SetLastErrorByStatus(Status);
+    }
+
+    /* Return length */
+    return RetVal;
 }
 
+/* FUNCTIONS *****************************************************************/
 
-UINT
-STDCALL
-GlobalGetAtomNameW(
-    ATOM nAtom,
-    wchar_t * lpBuffer,
-    int nSize
-    )
+/*
+ * @implemented
+ */
+ATOM
+WINAPI
+GlobalAddAtomA(LPCSTR lpString)
 {
-       return AWGLGetAtomName(&GlobalAtomTable, nAtom, lpBuffer, nSize);       
+    return InternalAddAtom(FALSE, FALSE, lpString);
 }
 
-
+/*
+ * @implemented
+ */
 ATOM
-STDCALL
-AddAtomA(
-    const char *lpString
-    )
+WINAPI
+GlobalAddAtomW(LPCWSTR lpString)
 {
-       UINT    BufLen = strlen(lpString);
-       wchar_t *lpBuffer = (wchar_t*)malloc(BufLen*2);
-       ATOM a;
-       ansi2unicode(lpBuffer, lpString,BufLen);
-       a = AWGLAddAtom(&GetTeb()->pPeb->LocalAtomTable, lpBuffer);
-       free(lpBuffer);
-       return a;
-       
+    return InternalAddAtom(FALSE, TRUE, (LPSTR)lpString);
 }
 
-
+/*
+ * @implemented
+ */
 ATOM
-STDCALL
-AddAtomW(
-    const wchar_t * lpString
-    )
+WINAPI
+GlobalDeleteAtom(ATOM nAtom)
 {
-       return AWGLAddAtom(&GetTeb()->pPeb->LocalAtomTable, lpString);
+    return InternalDeleteAtom(FALSE, nAtom);
 }
 
-
-
-
+/*
+ * @implemented
+ */
 ATOM
-STDCALL
-FindAtomA(
-    const char *lpString
-    )
+WINAPI
+GlobalFindAtomA(LPCSTR lpString)
 {
-       UINT    BufLen = strlen(lpString);
-       wchar_t *lpBuffer = (wchar_t *)malloc(BufLen*2);
-       ATOM a;
-       ansi2unicode(lpBuffer, lpString,BufLen);
-       a = AWGLFindAtom(&GetTeb()->pPeb->LocalAtomTable, lpBuffer);
-       free(lpBuffer);
-       return a;
+    return InternalFindAtom(FALSE, FALSE, lpString);
 }
 
-
+/*
+ * @implemented
+ */
 ATOM
-STDCALL
-FindAtomW(
-    const wchar_t * lpString
-    )
+WINAPI
+GlobalFindAtomW(LPCWSTR lpString)
 {
-       return AWGLFindAtom(&GetTeb()->pPeb->LocalAtomTable, lpString);
+    return InternalFindAtom(FALSE, TRUE, (LPSTR)lpString);
 }
 
-
-
+/*
+ * @implemented
+ */
 UINT
-STDCALL
-GetAtomNameA(
-    ATOM nAtom,
-    char  *lpBuffer,
-    int nSize
-    )
+WINAPI
+GlobalGetAtomNameA(ATOM nAtom,
+                   LPSTR lpBuffer,
+                   int nSize)
 {
-       LPWSTR lpUnicode = (wchar_t *)malloc(nSize *2);
-       UINT x = AWGLGetAtomName(&GlobalAtomTable, nAtom,lpUnicode,nSize);      
-       unicode2ansi(lpBuffer,lpUnicode,nSize);
-       free(lpUnicode);
-       return x;
+    return InternalGetAtomName(FALSE, FALSE, nAtom, lpBuffer, (DWORD)nSize);
 }
 
-
+/*
+ * @implemented
+ */
 UINT
-STDCALL
-GetAtomNameW(
-    ATOM nAtom,
-    wchar_t * lpBuffer,
-    int nSize
-    )
+WINAPI
+GlobalGetAtomNameW(ATOM nAtom,
+                   LPWSTR lpBuffer,
+                   int nSize)
 {
-       return AWGLGetAtomName(&GetTeb()->pPeb->LocalAtomTable,nAtom,lpBuffer,  nSize);
+    return InternalGetAtomName(FALSE,
+                               TRUE,
+                               nAtom,
+                               (LPSTR)lpBuffer,
+                               (DWORD)nSize);
 }
 
-ATOM
-GLDeleteAtom(
-    ATOMTABLE *at, ATOM nAtom
-    )
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+InitAtomTable(DWORD nSize)
 {
+    /* Normalize size */
+    if (nSize < 4 || nSize > 511) nSize = 37;
 
-       ATOMENTRY *lp;
-
-       /* a free slot has q == 0 && refcnt == 0 */
-       if((lp = GetAtomPointer(at,nAtom - ATOMBASE))) {
-               if(lp->idsize)
-                       lp->refcnt--;
-
-               if(lp->refcnt == 0) {
-                       free(at->AtomTable);
-                       at->AtomTable = NULL;
-                       free(at->AtomData);
-                       at->AtomData = NULL;
-                       return lp->q = 0;
-               }
-       }
-       return nAtom;
-
-
-
+    DPRINT("Here\n");
+    return NT_SUCCESS(RtlCreateAtomTable(nSize, &BaseLocalAtomTable));
 }
 
-
+/*
+ * @implemented
+ */
 ATOM
-AWGLAddAtom(
-     ATOMTABLE *at, const wchar_t *lpString
-       )
+WINAPI
+AddAtomA(LPCSTR lpString)
 {
-       ATOM            atom;
-       ATOMID          q;
-       LPATOMENTRY     lp,lpfree;
-       int             index,freeindex;
-       int             atomlen;
-       int             newlen;
-       
-       
-       
-       /* if we already have it, bump refcnt */
-       if((atom = AWGLFindAtom(at, lpString ))) {
-               lp = GetAtomPointer(at,atom - ATOMBASE);
-               if(lp->idsize) lp->refcnt++;
-               return atom;
-       }
-
-       /* add to a free slot */
-       q = AtomHashString(lpString,&atomlen);
-
-       lpfree    = 0;
-       freeindex = 0;
-
-       for(index = 0;(lp = GetAtomPointer(at,index));index++) {
-               if(lp->q == 0 && lp->refcnt == 0) {     
-                       if(lp->idsize > atomlen) {
-                               if ((lpfree == 0) ||
-                                           (lpfree->idsize > lp->idsize)) {
-                                       lpfree = lp;
-                                       freeindex = index;
-                               }
-                       }
-               }
-       }
-       /* intatoms do not take space in data, but do get new entries */
-       /* an INTATOM will have length of 0                           */
-       if(lpfree && atomlen) {
-               lpfree->q = q;
-               lpfree->refcnt = 1;
-               wcsncpy(&at->AtomData[lpfree->idx],lpString,atomlen);
-               return freeindex + ATOMBASE;
-       }
-
-       /* no space was available, or we have an INTATOM                */
-       /* so expand or create the table                                */
-       if(at->AtomTable == 0) {
-               at->AtomTable = (ATOMENTRY *) malloc(sizeof(ATOMENTRY));        
-               at->TableSize = 1;
-               lp = at->AtomTable;
-               index = 0;
-       } else {
-               at->TableSize++;
-               at->AtomTable = (ATOMENTRY *) realloc(
-                       (LPVOID) at->AtomTable,
-                       at->TableSize * sizeof(ATOMENTRY));
-               lp = &at->AtomTable[at->TableSize - 1];
-       }
-
-       /* set in the entry */
-       lp->refcnt = 1;
-       lp->q      = q;
-       lp->idsize = atomlen;
-       lp->idx    = 0;
-
-       /* add an entry if not intatom... */
-       if(atomlen) {
-               newlen = at->DataSize + atomlen;
-
-               if(at->AtomData == 0) {
-                       at->AtomData = (wchar_t *) malloc(newlen*2);
-                       lp->idx = 0;
-               } else {
-                       
-                       at->AtomData = (wchar_t *) realloc(at->AtomData,newlen*2);
-                       lp->idx = at->DataSize;
-               }
-
-               wcscpy(&at->AtomData[lp->idx],lpString);
-               at->DataSize = newlen;
-       }       
-
-       return index + ATOMBASE;
+    return InternalAddAtom(TRUE, FALSE, lpString);
 }
 
-
-
-
-
-
-
-
-
-
+/*
+ * @implemented
+ */
 ATOM
-AWGLFindAtom(
-     ATOMTABLE *at, const wchar_t *lpString
-    )
+WINAPI
+AddAtomW(LPCWSTR lpString)
 {
-
-       ATOMID          q;
-       LPATOMENTRY     lp;
-       int             index;
-       int             atomlen;
-       
-
-       
-
-       /* convert string to 'q', and get length */
-       q = AtomHashString(lpString,&atomlen);
-
-       /* find the q value, note: this could be INTATOM */
-       /* if q matches, then do case insensitive compare*/
-       for(index = 0;(lp = GetAtomPointer(at,index));index++) {
-               if(lp->q == q) {        
-                       if(HIWORD(lpString) == 0)
-                               return ATOMBASE + index;
-                       if(wcsicmp(&at->AtomData[lp->idx],lpString) == 0)
-                               return ATOMBASE + index;
-               }
-       }
-       return 0;
+    return InternalAddAtom(TRUE, TRUE, (LPSTR)lpString);
 }
 
-
-UINT
-AWGLGetAtomName(ATOMTABLE *at, ATOM atom, wchar_t *lpString,int len)
+/*
+ * @implemented
+ */
+ATOM
+WINAPI
+DeleteAtom(ATOM nAtom)
 {
-       
-       ATOMENTRY       *lp;
-       wchar_t         *atomstr;
-       int             atomlen;
-       
-       
-       
-       /* return the atom name, or create the INTATOM */
-       if((lp = GetAtomPointer(at,atom - ATOMBASE))) {
-               if(lp->idsize) {
-                       atomlen = wcslen(atomstr = &at->AtomData[lp->idx]);
-                       if (atomlen < len)
-                           wcscpy(lpString,atomstr);
-                       else {
-                           wcsncpy(lpString,atomstr,len-1);
-                           lpString[len-1] = '\0';
-                       }
-                       return (UINT)wcslen(lpString);
-               } else {
-                       //wsprintf((wchar *)lpString,"#%d",lp->q);
-                       return (UINT)wcslen(lpString);
-               }
-       }
-       return 0;
+    return InternalDeleteAtom(TRUE, nAtom);
 }
 
-
-/********************************************************/
-/* convert alphanumeric string to a 'q' value.                 */
-/* 'q' values do not need to be unique, they just limit */
-/* the search we need to make to find a string         */
-/********************************************************/
-
-static ATOMID
-AtomHashString(const wchar_t * lp,int *lplen)
+/*
+ * @implemented
+ */
+ATOM
+WINAPI
+FindAtomA(LPCSTR lpString)
 {
-       ATOMID  q;
-       wchar_t   *p,ch;
-       int     len;
-
-       /* if we have an intatom... */
-       if(HIWORD(lp) == 0) {
-               if(lplen) *lplen = 0;
-               return (ATOMID)lp;
-       }
-
-       /* convert the string to an internal representation */
-       for(p=(wchar_t *)lp,q=0,len=0;(p++,ch=*p++);len++)
-               q = (q<<1) + iswlower(ch)?towupper(ch):ch;
-
-       /* 0 is reserved for empty slots */
-       if(q == 0)
-               q++;
-
-       /* avoid strlen later */
-       /* check out with unicode */
-       if(lplen) {
-               *lplen = ++len;
-       }
-       return q;
+    return InternalFindAtom(TRUE, FALSE, lpString);
 }
 
-/********************************************************/
-/*     convert an atom index into a pointer into an    */
-/*     atom table.  This validates the pointer is in   */
-/*     range, and that the data is accessible          */
-/********************************************************/
-
-static ATOMENTRY *
-GetAtomPointer(ATOMTABLE *at,int index)
+/*
+ * @implemented
+ */
+ATOM
+WINAPI
+FindAtomW(LPCWSTR lpString)
 {
-       ATOMENTRY *lp;
-       
-       /* if no table, then no pointers */
-       if(at->AtomTable == 0)
-               return 0;
-
-       /* bad index */
-       if((index < 0) || (index >= at->TableSize))
-               return 0;
+    return InternalFindAtom(TRUE, TRUE, (LPSTR)lpString);
 
-       /* we have a pointer */
-       lp = &at->AtomTable[index];
-
-
-       /* is the index past stored data, validity check                */
-       /* LATER: is the size of the entry within the available space   */
-       if(lp->idx > at->DataSize)
-               return 0;
-
-       return lp;
 }
 
-int ansi2unicode( wchar_t *uni, char *ansi, int s)
+/*
+ * @implemented
+ */
+UINT
+WINAPI
+GetAtomNameA(ATOM nAtom,
+             LPSTR lpBuffer,
+             int nSize)
 {
-       register int i;
-       
-       for(i=0;i<=s;i++) 
-               uni[i] = (wchar_t)ansi[i];
-       return;
+    return InternalGetAtomName(TRUE, FALSE, nAtom, lpBuffer, (DWORD)nSize);
 }
 
-int unicode2ansi( char *ansi, wchar_t *uni, int s)
+/*
+ * @implemented
+ */
+UINT
+WINAPI
+GetAtomNameW(ATOM nAtom,
+             LPWSTR lpBuffer,
+             int nSize)
 {
-       register int i;
-       
-       for(i=0;i<=s;i++) 
-               ansi[i] = (char)uni[i];
-       return;
+    return InternalGetAtomName(TRUE,
+                               TRUE,
+                               nAtom,
+                               (LPSTR)lpBuffer,
+                               (DWORD)nSize);
 }
-
-
-
-
-
+/* EOF */