Implemented NTDLL atom support.

diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
index 97bd26a..48b01dc 100644
--- a/dlls/ntdll/Makefile.in
+++ b/dlls/ntdll/Makefile.in
@@ -8,6 +8,7 @@
 EXTRALIBS = $(LIBUNICODE) @IOKITLIB@
 
 C_SRCS = \
+	atom.c \
 	cdrom.c \
 	critsection.c \
 	debugbuffer.c \
diff --git a/dlls/ntdll/atom.c b/dlls/ntdll/atom.c
new file mode 100644
index 0000000..8bb66d3
--- /dev/null
+++ b/dlls/ntdll/atom.c
@@ -0,0 +1,419 @@
+/*
+ * Atom table functions
+ *
+ * Copyright 1993, 1994, 1995 Alexandre Julliard
+ * Copyright 2004,2005 Eric Pouech
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "ntstatus.h"
+
+#include "wine/server.h"
+#include "wine/unicode.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(atom);
+
+#define MAX_ATOM_LEN              255
+
+/******************************************************************
+ *		is_integral_atom
+ * Returns STATUS_SUCCESS if integral atom and 'pAtom' is filled
+ *         STATUS_INVALID_PARAMETER if 'atomstr' is too long
+ *         STATUS_MORE_ENTRIES otherwise
+ */
+static NTSTATUS is_integral_atom( LPCWSTR atomstr, size_t len, RTL_ATOM* pAtom )
+{
+    RTL_ATOM atom;
+
+    if (HIWORD( atomstr ))
+    {
+        const WCHAR* ptr = atomstr;
+        if (!len) return STATUS_INVALID_PARAMETER;
+
+        if (*ptr++ == '#')
+        {
+            atom = 0;
+            while (ptr < atomstr + len && *ptr >= '0' && *ptr <= '9')
+            {
+                atom = atom * 10 + *ptr++ - '0';
+            }
+            if (ptr > atomstr + 1 && ptr == atomstr + len) goto done;
+        }
+        if (len > MAX_ATOM_LEN) return STATUS_INVALID_PARAMETER;
+        return STATUS_MORE_ENTRIES;
+    }
+    else atom = LOWORD( atomstr );
+done:
+    if (atom >= MAXINTATOM) return STATUS_INVALID_PARAMETER;
+    *pAtom = atom;
+    return STATUS_SUCCESS;
+}
+
+/******************************************************************
+ *		RtlDeleteAtomFromAtomTable (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlDeleteAtomFromAtomTable( RTL_ATOM_TABLE table, RTL_ATOM atom )
+{
+    NTSTATUS    status;
+
+    TRACE( "%p %x\n", table, atom );
+    if (!table) status = STATUS_INVALID_PARAMETER;
+    else
+    {
+        SERVER_START_REQ( delete_atom )
+        {
+            req->atom = atom;
+            req->table = table;
+            status = wine_server_call( req );
+        }
+        SERVER_END_REQ;
+    }
+    return status;
+}
+
+/******************************************************************
+ *		RtlQueryAtomInAtomTable (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlQueryAtomInAtomTable( RTL_ATOM_TABLE table, RTL_ATOM atom, ULONG* ref,
+                                         ULONG* pin, WCHAR* name, ULONG* len )
+{
+    NTSTATUS    status = STATUS_SUCCESS;
+    WCHAR       full_name[MAX_ATOM_LEN];
+    DWORD       wlen = 0;
+
+    if (!table) status = STATUS_INVALID_PARAMETER;
+    else if (atom < MAXINTATOM)
+    {
+        if (!atom) return STATUS_INVALID_PARAMETER;
+        if (len)
+        {
+            static WCHAR fmt[] = {'#','%','d',0};
+            wlen = sprintfW( full_name, fmt, atom ) * sizeof(WCHAR);
+        }
+        if (ref) *ref = 1;
+        if (pin) *pin = 1;
+    }
+    else
+    {
+        SERVER_START_REQ( get_atom_information )
+        {
+            req->atom = atom;
+            req->table = table;
+            if (len) wine_server_set_reply( req, full_name, sizeof(full_name) );
+            status = wine_server_call( req );
+            if (status == STATUS_SUCCESS)
+            {
+                wlen = wine_server_reply_size( reply );
+                if (ref) *ref = reply->count;
+                if (pin) *pin = reply->pinned;
+            }
+        }
+        SERVER_END_REQ;
+    }
+    if (status == STATUS_SUCCESS && len)
+    {
+        if (*len > wlen)
+        {
+            *len = wlen;
+            memcpy( name, full_name, wlen );
+            name[wlen / sizeof(WCHAR)] = 0;
+        }
+        else status = STATUS_BUFFER_TOO_SMALL;
+    }
+
+    TRACE( "%p %x -> %s (%lu)\n",
+           table, atom, len ? debugstr_w(name) : NULL, status );
+    return status;
+}
+
+/******************************************************************
+ *		RtlCreateAtomTable (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlCreateAtomTable( ULONG size, RTL_ATOM_TABLE* table )
+{
+    NTSTATUS    status;
+
+    if (*table)
+    {
+        if (size) status = STATUS_INVALID_PARAMETER;
+        else status = STATUS_SUCCESS;
+    }
+    else
+    {
+        SERVER_START_REQ( init_atom_table )
+        {
+            req->entries = size;
+            status = wine_server_call( req );
+            *table = reply->table;
+        }
+        SERVER_END_REQ;
+    }
+    return status;
+}
+
+/******************************************************************
+ *		RtlDestroyAtomTable (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlDestroyAtomTable( RTL_ATOM_TABLE table )
+{
+    if (!table) return STATUS_INVALID_PARAMETER;
+    return NtClose( (HANDLE)table );
+}
+
+/******************************************************************
+ *		RtlAddAtomToAtomTable (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlAddAtomToAtomTable( RTL_ATOM_TABLE table, const WCHAR* name, RTL_ATOM* atom )
+{
+    NTSTATUS    status;
+
+    if (!table) status = STATUS_INVALID_PARAMETER;
+    else
+    {
+        size_t len = strlenW(name);
+        status = is_integral_atom( name, len, atom );
+        if (status == STATUS_MORE_ENTRIES)
+        {
+            SERVER_START_REQ( add_atom )
+            {
+                wine_server_add_data( req, name, len * sizeof(WCHAR) );
+                req->table = table;
+                status = wine_server_call( req );
+                *atom = reply->atom;
+            }
+            SERVER_END_REQ;
+        }
+    }
+    TRACE( "%p %s -> %x\n",
+           table, debugstr_w(name), status == STATUS_SUCCESS ? *atom : 0 );
+
+    return status;
+}
+
+/******************************************************************
+ *		RtlLookupAtomInAtomTable (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlLookupAtomInAtomTable( RTL_ATOM_TABLE table, const WCHAR* name, RTL_ATOM* atom )
+{
+    NTSTATUS    status;
+
+    if (!table) status = STATUS_INVALID_PARAMETER;
+    else
+    {
+        size_t len = strlenW(name);
+        status = is_integral_atom( name, len, atom );
+        if (status == STATUS_MORE_ENTRIES)
+        {
+            SERVER_START_REQ( find_atom )
+            {
+                wine_server_add_data( req, name, len * sizeof(WCHAR) );
+                req->table = table;
+                status = wine_server_call( req );
+                *atom = reply->atom;
+            }
+            SERVER_END_REQ;
+        }
+    }
+    TRACE( "%p %s -> %x\n",
+           table, debugstr_w(name), status == STATUS_SUCCESS ? *atom : 0 );
+    return status;
+}
+
+/******************************************************************
+ *		RtlEmptyAtomTable (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlEmptyAtomTable( RTL_ATOM_TABLE table, BOOLEAN delete_pinned )
+{
+    NTSTATUS    status;
+
+    if (!table) status = STATUS_INVALID_PARAMETER;
+    else
+    {
+        SERVER_START_REQ( empty_atom_table )
+        {
+            req->table = table;
+            req->if_pinned = delete_pinned;
+            status = wine_server_call( req );
+        }
+        SERVER_END_REQ;
+    }
+    return status;
+}
+
+/******************************************************************
+ *		RtlPinAtomInAtomTable (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlPinAtomInAtomTable( RTL_ATOM_TABLE table, RTL_ATOM atom )
+{
+    NTSTATUS    status = STATUS_INVALID_PARAMETER;
+
+    if (table && atom >= MAXINTATOM)
+    {
+        SERVER_START_REQ( set_atom_information )
+        {
+            req->table = table;
+            req->atom = atom;
+            req->pinned = TRUE;
+            status = wine_server_call( req );
+        }
+        SERVER_END_REQ;
+    }
+
+    return status;
+}
+
+/*************************************************
+ *        Global handle table management
+ *************************************************/
+
+/******************************************************************
+ *		NtAddAtom (NTDLL.@)
+ */
+NTSTATUS WINAPI NtAddAtom( const WCHAR* name, ULONG length, RTL_ATOM* atom )
+{
+    NTSTATUS    status;
+
+    status = is_integral_atom( name, length / sizeof(WCHAR), atom );
+    if (status == STATUS_MORE_ENTRIES)
+    {
+        SERVER_START_REQ( add_atom )
+        {
+            wine_server_add_data( req, name, length );
+            req->table = NULL;
+            status = wine_server_call( req );
+            *atom = reply->atom;
+        }
+        SERVER_END_REQ;
+    }
+    TRACE( "%s -> %x\n",
+           debugstr_wn(name, length/sizeof(WCHAR)), status == STATUS_SUCCESS ? *atom : 0 );
+    return status;
+}
+
+/******************************************************************
+ *		NtDeleteAtom (NTDLL.@)
+ */
+NTSTATUS WINAPI NtDeleteAtom(RTL_ATOM atom)
+{
+    NTSTATUS    status;
+
+    SERVER_START_REQ( delete_atom )
+    {
+        req->atom = atom;
+        req->table = NULL;
+        status = wine_server_call( req );
+    }
+    SERVER_END_REQ;
+    return status;
+}
+
+/******************************************************************
+ *		NtFindAtom (NTDLL.@)
+ */
+NTSTATUS WINAPI NtFindAtom( const WCHAR* name, ULONG length, RTL_ATOM* atom )
+{
+    NTSTATUS    status;
+
+    status = is_integral_atom( name, length / sizeof(WCHAR), atom );
+    if (status == STATUS_MORE_ENTRIES)
+    {
+        SERVER_START_REQ( find_atom )
+        {
+            wine_server_add_data( req, name, length );
+            req->table = NULL;
+            status = wine_server_call( req );
+            *atom = reply->atom;
+        }
+        SERVER_END_REQ;
+    }
+    TRACE( "%s -> %x\n",
+           debugstr_wn(name, length/sizeof(WCHAR)), status == STATUS_SUCCESS ? *atom : 0 );
+    return status;
+}
+
+/******************************************************************
+ *		NtQueryInformationAtom (NTDLL.@)
+ */
+NTSTATUS WINAPI NtQueryInformationAtom( RTL_ATOM atom, ATOM_INFORMATION_CLASS class,
+                                        RTL_ATOM_TABLE ptr, ULONG size, PULONG psize )
+{
+    NTSTATUS status;
+
+    switch (class)
+    {
+    case AtomBasicInformation:
+        {
+            ULONG name_len;
+            ATOM_BASIC_INFORMATION* abi = (ATOM_BASIC_INFORMATION*)ptr;
+
+            name_len = size - (sizeof(ATOM_BASIC_INFORMATION) - sizeof(WCHAR));
+
+            if (atom < MAXINTATOM)
+            {
+                if (!atom) status = STATUS_INVALID_PARAMETER;
+                else if (name_len >= 7 * sizeof(WCHAR))
+                {
+                    static WCHAR fmt[] = {'#','%','d',0};
+                    abi->NameLength = snprintfW( abi->Name, name_len / sizeof(WCHAR), fmt, atom ) * sizeof(WCHAR);
+                    abi->ReferenceCount = 1;
+                    abi->Pinned = 1;
+                    status = STATUS_SUCCESS;
+                }
+                else status = STATUS_BUFFER_TOO_SMALL;
+            }
+            else
+            {
+                SERVER_START_REQ( get_atom_information )
+                {
+                    req->atom = atom;
+                    req->table = NULL;
+                    if (name_len) wine_server_set_reply( req, abi->Name, name_len );
+                    status = wine_server_call( req );
+                    name_len = wine_server_reply_size( reply );
+                    if (status == STATUS_SUCCESS)
+                    {
+                        abi->NameLength = name_len;
+                        abi->ReferenceCount = reply->count;
+                        abi->Pinned = reply->pinned;
+                    }
+                }
+                SERVER_END_REQ;
+            }
+            TRACE( "%x -> %s (%lu)\n", atom, debugstr_wn(abi->Name, name_len/sizeof(WCHAR)), status );
+            if (psize)
+                *psize = sizeof(ATOM_BASIC_INFORMATION) - sizeof(WCHAR) + name_len;
+        }
+        break;
+    default:
+        FIXME( "Unsupported class %u\n", class );
+        status = STATUS_INVALID_INFO_CLASS;
+        break;
+    }
+    return status;
+}
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index fbc4759..ff19eee 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -66,6 +66,7 @@
 @ stdcall NtAcceptConnectPort(ptr long ptr long long ptr)
 @ stdcall NtAccessCheck(ptr long long ptr ptr ptr ptr ptr)
 @ stub NtAccessCheckAndAuditAlarm
+@ stdcall NtAddAtom(ptr long ptr)
 @ stdcall NtAdjustGroupsToken(long long ptr long ptr ptr)
 @ stdcall NtAdjustPrivilegesToken(long long long long long long)
 @ stub NtAlertResumeThread
@@ -103,6 +104,7 @@
 @ stub NtCreateToken
 @ stdcall NtCurrentTeb()
 @ stdcall NtDelayExecution(long ptr)
+@ stdcall NtDeleteAtom(long)
 @ stdcall NtDeleteFile(ptr)
 @ stdcall NtDeleteKey(long)
 @ stdcall NtDeleteValueKey(long ptr)
@@ -114,6 +116,7 @@
 @ stdcall NtEnumerateKey (long long long long long long)
 @ stdcall NtEnumerateValueKey (long long long long long long)
 @ stub NtExtendSection
+@ stdcall NtFindAtom(ptr long ptr)
 @ stdcall NtFlushBuffersFile(long ptr)
 @ stdcall NtFlushInstructionCache(long ptr long)
 @ stdcall NtFlushKey(long)
@@ -169,6 +172,7 @@
 @ stub NtQueryEaFile
 @ stdcall NtQueryEvent(long long ptr long ptr)
 @ stdcall NtQueryFullAttributesFile(ptr ptr)
+@ stdcall NtQueryInformationAtom(long long ptr ptr)
 @ stdcall NtQueryInformationFile(long ptr ptr long long)
 @ stub NtQueryInformationPort
 @ stdcall NtQueryInformationProcess(long long ptr long ptr)
@@ -292,6 +296,7 @@
 @ stdcall RtlAddAccessDeniedAceEx(ptr long long long ptr)
 @ stdcall RtlAddAce(ptr long long ptr long)
 @ stub RtlAddActionToRXact
+@ stdcall RtlAddAtomToAtomTable(ptr wstr ptr)
 @ stub RtlAddAttributeActionToRXact
 @ stub RtlAddAuditAccessAce
 @ stdcall RtlAddVectoredExceptionHandler(long ptr)
@@ -341,6 +346,7 @@
 @ stdcall RtlCopyUnicodeString(ptr ptr)
 @ stdcall RtlCreateAcl(ptr long long)
 @ stub RtlCreateAndSetSD
+@ stdcall RtlCreateAtomTable(long ptr)
 @ stdcall RtlCreateEnvironment(long ptr)
 @ stdcall RtlCreateHeap(long ptr long long ptr ptr)
 @ stdcall RtlCreateProcessParameters(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr)
@@ -364,7 +370,7 @@
 @ stub RtlDefaultNpAcl
 @ stub RtlDelete
 @ stdcall RtlDeleteAce(ptr long)
-@ stub RtlDeleteAtomFromAtomTable
+@ stdcall RtlDeleteAtomFromAtomTable(ptr long)
 @ stdcall RtlDeleteCriticalSection(ptr)
 @ stub RtlDeleteElementGenericTable
 @ stub RtlDeleteElementGenericTableAvl
@@ -374,6 +380,7 @@
 @ stdcall RtlDeleteRegistryValue(long ptr ptr)
 @ stdcall RtlDeleteResource(ptr)
 @ stdcall RtlDeleteSecurityObject(long)
+@ stdcall RtlDestroyAtomTable(ptr)
 @ stdcall RtlDestroyEnvironment(ptr)
 @ stdcall RtlDestroyHandleTable(ptr)
 @ stdcall RtlDestroyHeap(long)
@@ -387,6 +394,7 @@
 @ stdcall RtlDowncaseUnicodeString(ptr ptr long)
 @ stdcall RtlDumpResource(ptr)
 @ stdcall RtlDuplicateUnicodeString(long ptr ptr)
+@ stdcall RtlEmptyAtomTable(ptr long)
 @ stdcall -ret64 RtlEnlargedIntegerMultiply(long long)
 @ stdcall RtlEnlargedUnsignedDivide(long long long ptr)
 @ stdcall -ret64 RtlEnlargedUnsignedMultiply(long long)
@@ -507,6 +515,7 @@
 @ stdcall RtlLengthSid(ptr)
 @ stdcall RtlLocalTimeToSystemTime(ptr ptr)
 @ stdcall RtlLockHeap(long)
+@ stdcall RtlLookupAtomInAtomTable(ptr wstr ptr)
 @ stub RtlLookupElementGenericTable
 @ stdcall RtlMakeSelfRelativeSD(ptr ptr ptr)
 @ stdcall RtlMapGenericMask(long ptr)
@@ -527,10 +536,11 @@
 @ stdcall RtlOemToUnicodeN(ptr long ptr ptr long)
 @ stdcall RtlOpenCurrentUser(long ptr)
 @ stub RtlPcToFileHeader
+@ stdcall RtlPinAtomInAtomTable(ptr long)
 @ stdcall RtlPrefixString(ptr ptr long)
 @ stdcall RtlPrefixUnicodeString(ptr ptr long)
 @ stub RtlProtectHeap
-@ stub RtlQueryAtomInAtomTable
+@ stdcall RtlQueryAtomInAtomTable(ptr long ptr ptr ptr ptr)
 @ stub RtlQueryDepthSList
 @ stdcall RtlQueryEnvironmentVariable_U(ptr ptr ptr)
 @ stub RtlQueryHeapInformation
@@ -660,6 +670,7 @@
 @ stdcall ZwAcceptConnectPort(ptr long ptr long long ptr) NtAcceptConnectPort
 @ stdcall ZwAccessCheck(ptr long long ptr ptr ptr ptr ptr) NtAccessCheck
 @ stub ZwAccessCheckAndAuditAlarm
+@ stdcall ZwAddAtom(ptr long ptr) NtAddAtom
 @ stdcall ZwAdjustGroupsToken(long long long long long long) NtAdjustGroupsToken
 @ stdcall ZwAdjustPrivilegesToken(long long long long long long) NtAdjustPrivilegesToken
 @ stub ZwAlertResumeThread
@@ -696,6 +707,7 @@
 @ stdcall ZwCreateTimer(ptr long ptr long) NtCreateTimer
 @ stub ZwCreateToken
 @ stdcall ZwDelayExecution(long ptr) NtDelayExecution
+@ stdcall ZwDeleteAtom(long) NtDeleteAtom
 @ stdcall ZwDeleteFile(ptr) NtDeleteFile
 @ stdcall ZwDeleteKey(long) NtDeleteKey
 @ stdcall ZwDeleteValueKey(long ptr) NtDeleteValueKey
@@ -707,6 +719,7 @@
 @ stdcall ZwEnumerateKey(long long long ptr long ptr) NtEnumerateKey
 @ stdcall ZwEnumerateValueKey(long long long ptr long ptr) NtEnumerateValueKey
 @ stub ZwExtendSection
+@ stdcall ZwFindAtom(ptr long ptr) NtFindAtom
 @ stdcall ZwFlushBuffersFile(long ptr) NtFlushBuffersFile
 @ stdcall ZwFlushInstructionCache(long ptr long) NtFlushInstructionCache
 @ stdcall ZwFlushKey(long) NtFlushKey
@@ -758,6 +771,7 @@
 @ stdcall ZwQueryDirectoryObject(long ptr long long long ptr ptr) NtQueryDirectoryObject
 @ stub ZwQueryEaFile
 @ stdcall ZwQueryEvent(long long ptr long ptr) NtQueryEvent
+@ stdcall ZwQueryInformationAtom(long long ptr ptr) NtQueryInformationAtom
 @ stdcall ZwQueryInformationFile(long ptr ptr long long) NtQueryInformationFile
 @ stub ZwQueryInformationPort
 @ stdcall ZwQueryInformationProcess(long long ptr long ptr) NtQueryInformationProcess
@@ -973,15 +987,9 @@
 @ cdecl wcstol(wstr ptr long) NTDLL_wcstol
 @ cdecl wcstombs(ptr ptr long) NTDLL_wcstombs
 @ cdecl wcstoul(wstr ptr long) NTDLL_wcstoul
-@ stub NtAddAtom
-@ stub NtDeleteAtom
-@ stub NtFindAtom
 @ stub NtReadFileScatter
 @ stdcall NtSignalAndWaitForSingleObject(long long long ptr)
 @ stub NtWriteFileGather
-@ stub RtlAddAtomToAtomTable
-@ stub RtlCreateAtomTable
-@ stub RtlLookupAtomInAtomTable
 @ stdcall RtlTryEnterCriticalSection(ptr)
 @ stub RtlEnumerateProperties
 @ stub RtlSetPropertyClassId
diff --git a/include/winternl.h b/include/winternl.h
index 27dd7a3..4de3184 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1225,6 +1225,26 @@
   ULONG SectionSize;
 } PORT_MESSAGE_HEADER, *PPORT_MESSAGE_HEADER, PORT_MESSAGE, *PPORT_MESSAGE;
 
+typedef unsigned short RTL_ATOM, *PRTL_ATOM;
+
+/* Wine doesn't implement atom table as NT does:
+ * - in NT, atom tables are user space tables, which ntdll directly accesses
+ * - on Wine, (even local) atom tables are wineserver object, hence a HANDLE
+ */
+typedef struct atom_table *RTL_ATOM_TABLE, **PRTL_ATOM_TABLE;
+
+typedef enum _ATOM_INFORMATION_CLASS {
+   AtomBasicInformation         = 0,
+   AtomTableInformation         = 1,
+} ATOM_INFORMATION_CLASS;
+
+typedef struct _ATOM_BASIC_INFORMATION {
+   USHORT       ReferenceCount;
+   USHORT       Pinned;
+   USHORT       NameLength;
+   WCHAR        Name[1];
+} ATOM_BASIC_INFORMATION, *PATOM_BASIC_INFORMATION;
+
 /* FIXME: names probably not correct */
 typedef struct _RTL_HANDLE
 {
@@ -1433,6 +1453,7 @@
 void      WINAPI LdrShutdownProcess(void);
 void      WINAPI LdrShutdownThread(void);
 NTSTATUS  WINAPI NtAccessCheck(PSECURITY_DESCRIPTOR,HANDLE,ACCESS_MASK,PGENERIC_MAPPING,PPRIVILEGE_SET,PULONG,PULONG,NTSTATUS*);
+NTSTATUS  WINAPI NtAddAtom(const WCHAR*,ULONG,RTL_ATOM*);
 NTSTATUS  WINAPI NtAdjustGroupsToken(HANDLE,BOOLEAN,PTOKEN_GROUPS,ULONG,PTOKEN_GROUPS,PULONG);
 NTSTATUS  WINAPI NtAdjustPrivilegesToken(HANDLE,BOOLEAN,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
 NTSTATUS  WINAPI NtAlertThread(HANDLE ThreadHandle);
@@ -1453,6 +1474,7 @@
 NTSTATUS  WINAPI NtCreateSemaphore(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*,LONG,LONG);
 NTSTATUS  WINAPI NtCreateTimer(HANDLE*, ACCESS_MASK, const OBJECT_ATTRIBUTES*, TIMER_TYPE);
 NTSTATUS  WINAPI NtDelayExecution(BOOLEAN,const LARGE_INTEGER*);
+NTSTATUS  WINAPI NtDeleteAtom(RTL_ATOM);
 NTSTATUS  WINAPI NtDeleteFile(POBJECT_ATTRIBUTES);
 NTSTATUS  WINAPI NtDeleteKey(HKEY);
 NTSTATUS  WINAPI NtDeleteValueKey(HKEY,const UNICODE_STRING *);
@@ -1461,6 +1483,7 @@
 NTSTATUS  WINAPI NtDuplicateToken(HANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,SECURITY_IMPERSONATION_LEVEL,TOKEN_TYPE,PHANDLE);
 NTSTATUS  WINAPI NtEnumerateKey(HKEY,ULONG,KEY_INFORMATION_CLASS,void *,DWORD,DWORD *);
 NTSTATUS  WINAPI NtEnumerateValueKey(HKEY,ULONG,KEY_VALUE_INFORMATION_CLASS,PVOID,ULONG,PULONG);
+NTSTATUS  WINAPI NtFindAtom(const WCHAR*,ULONG,RTL_ATOM*);
 NTSTATUS  WINAPI NtFlushBuffersFile(HANDLE,IO_STATUS_BLOCK*);
 NTSTATUS  WINAPI NtFlushInstructionCache(HANDLE,LPCVOID,ULONG);
 NTSTATUS  WINAPI NtFlushKey(HKEY);
@@ -1499,6 +1522,7 @@
 NTSTATUS  WINAPI NtQueryDirectoryFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,PVOID,ULONG,FILE_INFORMATION_CLASS,BOOLEAN,PUNICODE_STRING,BOOLEAN);
 NTSTATUS  WINAPI NtQueryEaFile(HANDLE,PIO_STATUS_BLOCK,PVOID,ULONG,BOOLEAN,PVOID,ULONG,PVOID,BOOLEAN);
 NTSTATUS  WINAPI NtQueryFullAttributesFile(const OBJECT_ATTRIBUTES*,FILE_NETWORK_OPEN_INFORMATION*);
+NTSTATUS  WINAPI NtQueryInformationAtom(RTL_ATOM,ATOM_INFORMATION_CLASS,RTL_ATOM_TABLE,ULONG,ULONG*);
 NTSTATUS  WINAPI NtQueryInformationFile(HANDLE,PIO_STATUS_BLOCK,PVOID,LONG,FILE_INFORMATION_CLASS);
 NTSTATUS  WINAPI NtQueryInformationProcess(HANDLE,PROCESSINFOCLASS,PVOID,ULONG,PULONG);
 NTSTATUS  WINAPI NtQueryInformationThread(HANDLE,THREADINFOCLASS,PVOID,ULONG,PULONG);
@@ -1564,6 +1588,7 @@
 NTSTATUS  WINAPI RtlAddAccessAllowedAceEx(PACL,DWORD,DWORD,DWORD,PSID);
 NTSTATUS  WINAPI RtlAddAccessDeniedAce(PACL,DWORD,DWORD,PSID);
 NTSTATUS  WINAPI RtlAddAccessDeniedAceEx(PACL,DWORD,DWORD,DWORD,PSID);
+NTSTATUS  WINAPI RtlAddAtomToAtomTable(RTL_ATOM_TABLE,const WCHAR*,RTL_ATOM*);
 PVOID     WINAPI RtlAddVectoredExceptionHandler(ULONG,PVECTORED_EXCEPTION_HANDLER);
 DWORD     WINAPI RtlAdjustPrivilege(DWORD,DWORD,DWORD,DWORD);
 NTSTATUS  WINAPI RtlAllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY,BYTE,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,PSID *);
@@ -1597,6 +1622,7 @@
 void      WINAPI RtlCopyString(STRING*,const STRING*);
 void      WINAPI RtlCopyUnicodeString(UNICODE_STRING*,const UNICODE_STRING*);
 NTSTATUS  WINAPI RtlCreateAcl(PACL,DWORD,DWORD);
+NTSTATUS  WINAPI RtlCreateAtomTable(ULONG,RTL_ATOM_TABLE*);
 NTSTATUS  WINAPI RtlCreateEnvironment(BOOLEAN, PWSTR*);
 HANDLE    WINAPI RtlCreateHeap(ULONG,PVOID,ULONG,ULONG,PVOID,PRTL_HEAP_DEFINITION);
 NTSTATUS  WINAPI RtlCreateProcessParameters(RTL_USER_PROCESS_PARAMETERS**,const UNICODE_STRING*,
@@ -1610,11 +1636,13 @@
 NTSTATUS  WINAPI RtlCreateUserThread(HANDLE,const SECURITY_DESCRIPTOR*,BOOLEAN,PVOID,SIZE_T,SIZE_T,PRTL_THREAD_START_ROUTINE,void*,HANDLE*,CLIENT_ID*);
 
 NTSTATUS  WINAPI RtlDeleteAce(PACL,DWORD);
+NTSTATUS  WINAPI RtlDeleteAtomFromAtomTable(RTL_ATOM_TABLE,RTL_ATOM);
 NTSTATUS  WINAPI RtlDeleteCriticalSection(RTL_CRITICAL_SECTION *);
 NTSTATUS  WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR);
 void      WINAPI RtlDeleteResource(LPRTL_RWLOCK);
 DWORD     WINAPI RtlDeleteSecurityObject(DWORD);
 PRTL_USER_PROCESS_PARAMETERS WINAPI RtlDeNormalizeProcessParams(RTL_USER_PROCESS_PARAMETERS*);
+NTSTATUS  WINAPI RtlDestroyAtomTable(RTL_ATOM_TABLE);
 NTSTATUS  WINAPI RtlDestroyEnvironment(PWSTR);
 NTSTATUS  WINAPI RtlDestroyHandleTable(RTL_HANDLE_TABLE *);
 HANDLE    WINAPI RtlDestroyHeap(HANDLE);
@@ -1628,6 +1656,7 @@
 void      WINAPI RtlDumpResource(LPRTL_RWLOCK);
 NTSTATUS  WINAPI RtlDuplicateUnicodeString(int,const UNICODE_STRING*,UNICODE_STRING*);
 
+NTSTATUS  WINAPI RtlEmptyAtomTable(RTL_ATOM_TABLE,BOOLEAN);
 LONGLONG  WINAPI RtlEnlargedIntegerMultiply(INT,INT);
 ULONGLONG WINAPI RtlEnlargedUnsignedMultiply(UINT,UINT);
 UINT      WINAPI RtlEnlargedUnsignedDivide(ULONGLONG,UINT,UINT *);
@@ -1726,6 +1755,7 @@
 DWORD     WINAPI RtlLengthSid(PSID);
 NTSTATUS  WINAPI RtlLocalTimeToSystemTime(const LARGE_INTEGER*,PLARGE_INTEGER);
 BOOLEAN   WINAPI RtlLockHeap(HANDLE);
+NTSTATUS  WINAPI RtlLookupAtomInAtomTable(RTL_ATOM_TABLE,const WCHAR*,RTL_ATOM*);
 
 NTSTATUS  WINAPI RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD);
 void      WINAPI RtlMapGenericMask(PACCESS_MASK,const GENERIC_MAPPING*);
@@ -1744,9 +1774,11 @@
 NTSTATUS  WINAPI RtlOemToUnicodeN(LPWSTR,DWORD,LPDWORD,LPCSTR,DWORD);
 DWORD     WINAPI RtlOpenCurrentUser(ACCESS_MASK,PHKEY);
 
+NTSTATUS  WINAPI RtlPinAtomInAtomTable(RTL_ATOM_TABLE,RTL_ATOM);
 BOOLEAN   WINAPI RtlPrefixString(const STRING*,const STRING*,BOOLEAN);
 BOOLEAN   WINAPI RtlPrefixUnicodeString(const UNICODE_STRING*,const UNICODE_STRING*,BOOLEAN);
 
+NTSTATUS  WINAPI RtlQueryAtomInAtomTable(RTL_ATOM_TABLE,RTL_ATOM,ULONG*,ULONG*,WCHAR*,ULONG*);
 NTSTATUS  WINAPI RtlQueryEnvironmentVariable_U(PWSTR,PUNICODE_STRING,PUNICODE_STRING);
 NTSTATUS  WINAPI RtlQueryInformationAcl(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS);
 NTSTATUS  WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID);