[REDUNDANT/ARCHIVAL] Ntdll atom stuff
György 'Nog' Jeney
nog at sdf.lonestar.org
Mon Apr 7 07:15:30 CDT 2003
Here's my implementation of the ntdll atom functions I hacked toghether
during
last week, I'm posting it here just incase someone finds use for them some
day.
-------------- next part --------------
--- ../cleanwine/include/winternl.h 2003-04-05 08:33:39.000000000 +0200
+++ include/winternl.h 2003-04-07 12:10:48.000000000 +0200
@@ -764,6 +764,25 @@
typedef BOOLEAN (WINAPI * PWINSTATIONQUERYINFORMATIONW)(HANDLE,ULONG,WINSTATIONINFOCLASS,PVOID,ULONG,PULONG);
+typedef struct _ATOM_BASIC_INFORMATION
+{
+ USHORT RefCount;
+ USHORT Pin;
+ USHORT NameLen;
+ WCHAR Name[1];
+} ATOM_BASIC_INFORMATION, *PATOM_BASIC_INFORMATION;
+
+typedef WORD RTL_ATOM;
+typedef WORD *PRTL_ATOM;
+
+typedef PVOID RTL_ATOM_TABLE;
+typedef PVOID *PRTL_ATOM_TABLE;
+
+typedef enum _ATOM_INFORMATION_CLASS {
+ AtomBasicInformation,
+ AtomTableInformation
+} ATOM_INFORMATION_CLASS, *PATOM_INFORMATION_CLASS;
+
/***********************************************************************
* Defines
*/
@@ -822,6 +841,7 @@
void WINAPIV DbgPrint(LPCSTR fmt, ...);
NTSTATUS WINAPI NtAccessCheck(PSECURITY_DESCRIPTOR,HANDLE,ACCESS_MASK,PGENERIC_MAPPING,PPRIVILEGE_SET,PULONG,PULONG,PBOOLEAN);
+NTSTATUS WINAPI NtAddAtom(PCWSTR,PRTL_ATOM);
NTSTATUS WINAPI NtAdjustPrivilegesToken(HANDLE,BOOLEAN,PTOKEN_PRIVILEGES,DWORD,PTOKEN_PRIVILEGES,PDWORD);
NTSTATUS WINAPI NtAllocateVirtualMemory(HANDLE,PVOID*,PVOID,ULONG*,ULONG,ULONG);
NTSTATUS WINAPI NtClearEvent(HANDLE);
@@ -831,12 +851,14 @@
NTSTATUS WINAPI NtCreateKey(PHKEY,ACCESS_MASK,const OBJECT_ATTRIBUTES*,ULONG,const UNICODE_STRING*,ULONG,PULONG);
NTSTATUS WINAPI NtCreateSection(HANDLE*,ACCESS_MASK,const OBJECT_ATTRIBUTES*,const LARGE_INTEGER*,ULONG,ULONG,HANDLE);
NTSTATUS WINAPI NtCreateSemaphore(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*,ULONG,ULONG);
+NTSTATUS WINAPI NtDeleteAtom(RTL_ATOM);
NTSTATUS WINAPI NtDeleteKey(HKEY);
NTSTATUS WINAPI NtDeleteValueKey(HKEY,const UNICODE_STRING *);
NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,PVOID,ULONG,PVOID,ULONG);
NTSTATUS WINAPI NtDuplicateObject(HANDLE,HANDLE,HANDLE,PHANDLE,ACCESS_MASK,ULONG,ULONG);
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(PCWSTR,PRTL_ATOM);
NTSTATUS WINAPI NtFlushKey(HKEY);
NTSTATUS WINAPI NtFlushVirtualMemory(HANDLE,LPCVOID*,ULONG*,ULONG);
NTSTATUS WINAPI NtFreeVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG);
@@ -854,6 +876,7 @@
NTSTATUS WINAPI NtOpenThreadToken(HANDLE,DWORD,BOOLEAN,HANDLE *);
NTSTATUS WINAPI NtProtectVirtualMemory(HANDLE,PVOID*,ULONG*,ULONG,ULONG*);
NTSTATUS WINAPI NtPulseEvent(HANDLE,PULONG);
+NTSTATUS WINAPI NtQueryInformationAtom(RTL_ATOM,ATOM_INFORMATION_CLASS,PVOID,ULONG,PULONG);
NTSTATUS WINAPI NtQueueApcThread(HANDLE,PNTAPCFUNC,ULONG_PTR,ULONG_PTR,ULONG_PTR);
NTSTATUS WINAPI NtQueryInformationProcess(HANDLE,PROCESSINFOCLASS,PVOID,ULONG,PULONG);
NTSTATUS WINAPI NtQueryInformationThread(HANDLE,THREADINFOCLASS,PVOID,ULONG,PULONG);
@@ -894,6 +917,7 @@
NTSTATUS WINAPI RtlAddAce(PACL,DWORD,DWORD,PACE_HEADER,DWORD);
BOOL WINAPI RtlAddAccessAllowedAce(PACL,DWORD,DWORD,PSID);
BOOL WINAPI RtlAddAccessAllowedAceEx(PACL,DWORD,DWORD,DWORD,PSID);
+NTSTATUS WINAPI RtlAddAtomToAtomTable(RTL_ATOM_TABLE,PCWSTR,PRTL_ATOM);
DWORD WINAPI RtlAdjustPrivilege(DWORD,DWORD,DWORD,DWORD);
BOOLEAN WINAPI RtlAllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY,BYTE,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,PSID *);
PVOID WINAPI RtlAllocateHeap(HANDLE,ULONG,ULONG);
@@ -920,15 +944,18 @@
void WINAPI RtlCopyString(STRING*,const STRING*);
void WINAPI RtlCopyUnicodeString(UNICODE_STRING*,const UNICODE_STRING*);
NTSTATUS WINAPI RtlCreateAcl(PACL,DWORD,DWORD);
+NTSTATUS WINAPI RtlCreateAtomTable(ULONG,PRTL_ATOM_TABLE);
DWORD WINAPI RtlCreateEnvironment(DWORD,DWORD);
HANDLE WINAPI RtlCreateHeap(ULONG,PVOID,ULONG,ULONG,PVOID,PRTL_HEAP_DEFINITION);
NTSTATUS WINAPI RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR,DWORD);
BOOLEAN WINAPI RtlCreateUnicodeString(PUNICODE_STRING,LPCWSTR);
BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCSTR);
+NTSTATUS WINAPI RtlDeleteAtomFromAtomTable(RTL_ATOM_TABLE,RTL_ATOM);
NTSTATUS WINAPI RtlDeleteCriticalSection(RTL_CRITICAL_SECTION *);
void WINAPI RtlDeleteResource(LPRTL_RWLOCK);
DWORD WINAPI RtlDeleteSecurityObject(DWORD);
+NTSTATUS WINAPI RtlDestroyAtomTable(RTL_ATOM_TABLE);
DWORD WINAPI RtlDestroyEnvironment(DWORD);
HANDLE WINAPI RtlDestroyHeap(HANDLE);
BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(LPWSTR,PUNICODE_STRING,DWORD,DWORD);
@@ -966,6 +993,7 @@
ULONG WINAPI RtlFindSetBitsAndClear(PRTL_BITMAP,ULONG,ULONG);
ULONG WINAPI RtlFindSetRuns(PCRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOLEAN);
BOOLEAN WINAPI RtlFirstFreeAce(PACL,PACE_HEADER *);
+NTSTATUS WINAPI RtlEmptyAtomTable(RTL_ATOM_TABLE,BOOLEAN);
NTSTATUS WINAPI RtlFormatCurrentUserKeyPath(PUNICODE_STRING);
void WINAPI RtlFreeAnsiString(PANSI_STRING);
BOOLEAN WINAPI RtlFreeHeap(HANDLE,ULONG,PVOID);
@@ -1017,6 +1045,7 @@
DWORD WINAPI RtlLengthSid(PSID);
NTSTATUS WINAPI RtlLocalTimeToSystemTime(const LARGE_INTEGER*,PLARGE_INTEGER);
BOOLEAN WINAPI RtlLockHeap(HANDLE);
+NTSTATUS WINAPI RtlLookupAtomInAtomTable(RTL_ATOM_TABLE,PCWSTR,PRTL_ATOM);
NTSTATUS WINAPI RtlMakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD);
NTSTATUS WINAPI RtlMultiByteToUnicodeN(LPWSTR,DWORD,LPDWORD,LPCSTR,DWORD);
@@ -1033,9 +1062,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,PULONG,PULONG,PWSTR,PULONG);
DWORD WINAPI RtlQueryEnvironmentVariable_U(DWORD,PUNICODE_STRING,PUNICODE_STRING) ;
NTSTATUS WINAPI RtlQueryTimeZoneInformation(LPTIME_ZONE_INFORMATION);
void WINAPI RtlRaiseException(PEXCEPTION_RECORD);
--- ../cleanwine/dlls/ntdll/Makefile.in 2003-04-05 08:32:52.000000000 +0200
+++ dlls/ntdll/Makefile.in 2003-04-05 11:36:07.000000000 +0200
@@ -71,6 +71,7 @@
$(TOPOBJDIR)/win32/except.c \
$(TOPOBJDIR)/win32/kernel32.c \
$(TOPOBJDIR)/win32/newfns.c \
+ atom.c \
cdrom.c \
critsection.c \
debugtools.c \
--- /dev/null 1970-01-01 02:00:00.000000000 +0200
+++ dlls/ntdll/atom.c 2003-04-07 13:58:08.000000000 +0200
@@ -0,0 +1,523 @@
+/* Ntdll atom API implementation
+ *
+ * Copyright 2003 Gyorgy 'Nog' Jeney
+ *
+ * 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 "winternl.h"
+#include "wtypes.h"
+#include "ntstatus.h"
+#include "winnt.h"
+#include "wine/debug.h"
+#include "wine/server.h"
+#include "wine/unicode.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(atom);
+
+#define MAX_ATOM_LEN 255
+
+/***********************************************************************
+ * ATOM_IsIntAtom
+ */
+static BOOLEAN ATOM_IsIntAtom(LPCWSTR atomstr, WORD *atomid)
+{
+ UINT atom = 0;
+ if(!HIWORD(atomstr)) atom = LOWORD(atomstr);
+ else {
+ if(*atomstr++ != '#') return FALSE;
+ while (*atomstr >= '0' && *atomstr <= '9') {
+ atom = atom * 10 + *atomstr - '0';
+ atomstr++;
+ }
+ if(*atomstr) return FALSE;
+ }
+ if(atom >= MAXINTATOM)
+ atom = 0;
+ *atomid = atom;
+ return TRUE;
+}
+
+/****************************************************************
+ * NtAddAtom [ntdll.@]
+ *
+ * Adds an atom to the global atom table.
+ *
+ * PARAMS:
+ * AtomName [I]: The value of the atom.
+ * Atom [O]: The assigned value of the atom.
+ *
+ * RETURNS:
+ * Status.
+ */
+NTSTATUS WINAPI NtAddAtom(IN PCWSTR AtomName, OUT PRTL_ATOM Atom)
+{
+ NTSTATUS res;
+
+ TRACE("(%s, %p)\n", debugstr_w(AtomName), Atom);
+
+ if(ATOM_IsIntAtom(AtomName, Atom)) {
+ if(*Atom) return STATUS_SUCCESS;
+ else return STATUS_INVALID_PARAMETER;
+ }
+
+ SERVER_START_REQ(add_atom) {
+ wine_server_add_data(req, AtomName, strlenW(AtomName) * sizeof(WCHAR));
+ if(!(res = wine_server_call(req)))
+ *Atom = reply->atom;
+ }
+ SERVER_END_REQ;
+
+ return res;
+}
+
+/****************************************************************
+ * NtDeleteAtom [ntdll.@]
+ *
+ * Deletes the specified atom from the global atom table.
+ *
+ * PARAMS:
+ * Atom: [I]: Specifier of atom to delete.
+ *
+ * RETURNS:
+ * Status.
+ */
+NTSTATUS WINAPI NtDeleteAtom(IN RTL_ATOM Atom)
+{
+ NTSTATUS res;
+
+ TRACE("(%x)\n", Atom);
+
+ if(Atom < MAXINTATOM)
+ return STATUS_SUCCESS;
+
+ SERVER_START_REQ(delete_atom) {
+ req->atom = Atom;
+ res = wine_server_call(req);
+ } SERVER_END_REQ;
+
+ return res;
+}
+
+/****************************************************************
+ * NtFindAtom [ntdll.@]
+ *
+ * Finds an atom in the global atom table.
+ *
+ * PARAMS:
+ * AtomName [I]: Name of the atom to find in the global atom table.
+ * Atom [O]: The specifier to the atom found.
+ *
+ * RETURNS:
+ * Status.
+ */
+NTSTATUS WINAPI NtFindAtom(IN PCWSTR AtomName, OUT PRTL_ATOM Atom)
+{
+ NTSTATUS res;
+
+ TRACE("(%s, %p)\n", debugstr_w(AtomName), Atom);
+
+ SERVER_START_REQ(find_atom) {
+ wine_server_add_data(req, AtomName, strlenW(AtomName) * sizeof(WCHAR));
+ if(!(res = wine_server_call(req)))
+ *Atom = reply->atom;
+ } SERVER_END_REQ;
+
+ return res;
+}
+
+/****************************************************************
+ * NtQueryInformationAtom [ntdll.@]
+ *
+ * Returns information about the specified global atom.
+ *
+ * PARAMS:
+ * Atom [I]: The atom to request info about.
+ * AtomInfoClass [I]: The information to request.
+ * AtomInfo [O]: Buffer to hold the returned information.
+ * AtomInfoLen [I]: The length of the buffer pointed to by AtomInfo.
+ * RetLen [I]: The number of bytes actually used in AtomInfo.
+ *
+ * RETURNS:
+ * Status.
+ */
+NTSTATUS WINAPI NtQueryInformationAtom(IN RTL_ATOM Atom, IN ATOM_INFORMATION_CLASS
+ AtomInfoClass, OUT PVOID AtomInfo, ULONG AtomInfoLen, PULONG RetLen)
+{
+ NTSTATUS res = 0;
+ WCHAR full_name[MAX_ATOM_LEN];
+
+ TRACE("(%x, %x, %p, %lx, %p)\n", Atom, AtomInfoClass, AtomInfo, AtomInfoLen,
+ RetLen);
+
+ switch(AtomInfoClass) {
+ case AtomBasicInformation: {
+ PATOM_BASIC_INFORMATION info = AtomInfo;
+ USHORT RefCount, Pin, len;
+
+ TRACE("AtomBasicInformation requested\n");
+
+ if(Atom < MAXINTATOM) {
+ *RetLen = AtomInfoLen - sizeof(ATOM_BASIC_INFORMATION);
+ return RtlQueryAtomInAtomTable(NULL, Atom, &info->RefCount, &info->Pin, info->Name, RetLen);
+ }
+
+ SERVER_START_REQ(atom_query_information) {
+ req->atom = Atom;
+ wine_server_set_reply(req, full_name, sizeof(full_name));
+ if(!(res = wine_server_call(req))) {
+ len = wine_server_reply_size(reply);
+ RefCount = reply->refcount;
+ Pin = reply->pin;
+ }
+ } SERVER_END_REQ;
+ if(res)
+ break;
+
+ len /= sizeof(WCHAR);
+
+ if(AtomInfoLen < (sizeof(ATOM_BASIC_INFORMATION) + len))
+ return STATUS_BUFFER_TOO_SMALL;
+
+ info->RefCount = RefCount;
+ info->Pin = Pin;
+ info->NameLen = len;
+ full_name[len] = 0;
+ strcpyW(info->Name, full_name);
+
+ TRACE("Found info: ref: %x, pin: %x, namelen: %x, name: %s\n", RefCount,
+ Pin, len, debugstr_w(full_name));
+ break;
+ }
+
+ case AtomTableInformation:
+ FIXME("AtomTableInformation not implemented\n");
+ res = STATUS_NOT_IMPLEMENTED;
+ break;
+
+ default:
+ FIXME("Info class %x not implemented\n", AtomInfoClass);
+ res = STATUS_NOT_IMPLEMENTED;
+ }
+
+ return res;
+}
+
+/****************************************************************
+ * RtlCreateAtomTable [ntdll.@]
+ *
+ * Creates an atom table.
+ *
+ * PARAMS:
+ * Size [I]: The size of the atom table to create.
+ * Table [O]: Handle to the atom table.
+ *
+ * RETURNS:
+ * Status.
+ *
+ * NOTES:
+ * If *Table is not null then this function thinks that it is getting an
+ * already created atom table.
+ */
+NTSTATUS WINAPI RtlCreateAtomTable(IN ULONG Size, PRTL_ATOM_TABLE Table)
+{
+ NTSTATUS res;
+
+ TRACE("(%ld, %p)\n", Size, Table);
+
+ if(*Table)
+ return STATUS_SUCCESS;
+
+ SERVER_START_REQ(create_atom_table) {
+ req->entries = Size;
+ if(!(res = wine_server_call(req)))
+ *Table = reply->table;
+ } SERVER_END_REQ;
+
+ return res;
+}
+
+/****************************************************************
+ * RtlDestroyAtomTable [ntdll.@]
+ *
+ * Destroys an Atom table.
+ *
+ * PARAMS:
+ * Table [I]: Pointer to the atom table to destroy.
+ *
+ * RETURNS:
+ * Status.
+ */
+NTSTATUS WINAPI RtlDestroyAtomTable(IN RTL_ATOM_TABLE Table)
+{
+ NTSTATUS res;
+
+ TRACE("(%p)\n", Table);
+
+ SERVER_START_REQ(destroy_atom_table) {
+ req->table = Table;
+ res = wine_server_call(req);
+ } SERVER_END_REQ;
+
+ return res;
+}
+
+/****************************************************************
+ * RtlEmptyAtomTable [ntdll.@]
+ *
+ * Removes all atoms from the specified atom table.
+ *
+ * PARAMS:
+ * Table [I]: Handle to table to empty.
+ * DeletePinned [I]: Also removed pinned atoms.
+ *
+ * RETURNS:
+ * Status.
+ */
+NTSTATUS WINAPI RtlEmptyAtomTable(IN RTL_ATOM_TABLE Table, IN BOOLEAN DeletePinned)
+{
+ NTSTATUS res;
+
+ TRACE("(%p, %x)\n", Table, DeletePinned);
+
+ SERVER_START_REQ(empty_atom_table) {
+ req->table = Table;
+ req->delpinned = DeletePinned;
+ res = wine_server_call(req);
+ } SERVER_END_REQ;
+
+ return res;
+}
+
+/****************************************************************
+ * RtlAddAtomToAtomTable [ntdll.@]
+ *
+ * Adds an atom to an atom table.
+ *
+ * PARAMS:
+ * Table [I]: Table to add the atom to.
+ * AtomName [I]: Name of atom to add.
+ * Atom [O]: Handle to the atom.
+ *
+ * RETURNS:
+ * Status.
+ */
+NTSTATUS WINAPI RtlAddAtomToAtomTable(IN RTL_ATOM_TABLE Table, IN PCWSTR AtomName,
+ OUT PRTL_ATOM Atom)
+{
+ NTSTATUS res;
+
+ TRACE("(%p, %s, %p)\n", Table, debugstr_w(AtomName), Atom);
+
+ if(ATOM_IsIntAtom(AtomName, Atom)) {
+ if(*Atom) return STATUS_SUCCESS;
+ else return STATUS_INVALID_PARAMETER;
+ }
+
+ SERVER_START_REQ(add_atom_to_atom_table) {
+ wine_server_add_data(req, AtomName, strlenW(AtomName) * sizeof(WCHAR));
+ req->table = Table;
+ if(!(res = wine_server_call(req)))
+ *Atom = reply->atom;
+ } SERVER_END_REQ;
+
+ return res;
+}
+
+/****************************************************************
+ * RtlDeleteAtomFromAtomTable [ntdll.@]
+ *
+ * Removes the specified atom from the specified atom table.
+ *
+ * PARAMS:
+ * Table [I]: Table to delete the specified atom from.
+ * Atom [I]: The atom to delete from the table.
+ *
+ * RETURNS:
+ * Status.
+ */
+NTSTATUS WINAPI RtlDeleteAtomFromAtomTable(IN RTL_ATOM_TABLE Table, IN RTL_ATOM Atom)
+{
+ NTSTATUS res;
+
+ TRACE("(%p, %x)\n", Table, Atom);
+
+ if(Atom < MAXINTATOM)
+ return STATUS_SUCCESS;
+
+ SERVER_START_REQ(delete_atom_from_atom_table) {
+ req->table = Table;
+ req->atom = Atom;
+ res = wine_server_call(req);
+ } SERVER_END_REQ;
+
+ return res;
+}
+
+/****************************************************************
+ * RtlLookupAtomInAtomTable [ntdll.@]
+ *
+ * Finds an Atom in the specified atom table.
+ *
+ * PARAMS:
+ * Table [I]: The atom table to search.
+ * Name [I]: The name of the atom to find.
+ * Atom [O]: The handle of the found atom.
+ *
+ * RETURNS:
+ * Status.
+ */
+NTSTATUS WINAPI RtlLookupAtomInAtomTable(IN RTL_ATOM_TABLE Table, IN PCWSTR Name, OUT PRTL_ATOM Atom)
+{
+ NTSTATUS res;
+
+ TRACE("(%p, %s, %p)\n", Table, debugstr_w(Name), Atom);
+
+ if(ATOM_IsIntAtom(Name, Atom)) {
+ if(*Atom) return STATUS_SUCCESS;
+ else return STATUS_INVALID_PARAMETER;
+ }
+
+ SERVER_START_REQ(lookup_atom_in_atom_table) {
+ wine_server_add_data(req, Name, strlenW(Name) * sizeof(WCHAR));
+ req->table = Table;
+ if(!(res = wine_server_call(req)))
+ *Atom = reply->atom;
+ } SERVER_END_REQ;
+
+ return res;
+}
+
+/****************************************************************
+ * RtlPinAtomInAtomTable [ntdll.@]
+ *
+ * Pins the specified atom in the specified atom table.
+ *
+ * PARAMS:
+ * Table [I]: The table in which to pin the atom.
+ * Atom [I]: The atom to pin.
+ *
+ * RETURNS:
+ * Status.
+ *
+ * NOTES:
+ * Pinning an atom realy only sets a flag in the atom table entry that this
+ * atom is locked. Multiple calls to this fucntion with the same atom in the
+ * same table will do nothing eaven though RtlQueryAtomInAtomTable does have a
+ * pincount field.
+ */
+NTSTATUS WINAPI RtlPinAtomInAtomTable(IN RTL_ATOM_TABLE Table, IN RTL_ATOM Atom)
+{
+ NTSTATUS res;
+
+ TRACE("(%p, %x)\n", Table, Atom);
+
+ if(Atom < MAXINTATOM)
+ return STATUS_SUCCESS;
+
+ SERVER_START_REQ(pin_atom_in_atom_table) {
+ req->table = Table;
+ req->atom = Atom;
+ res = wine_server_call(req);
+ } SERVER_END_REQ;
+
+ return res;
+}
+
+/****************************************************************
+ * RtlQueryAtomInAtomTable [ntdll.@]
+ *
+ * Returns information about an atom in the specified atom table.
+ *
+ * PARAMS:
+ * Table [I]: The table that the atom's in.
+ * Atom [I]: The atom to query.
+ * RefCount [O]: How many times has the atom been added to the table.
+ * PinCount [O]: How many times has the atom been pinned.
+ * AtomName [O]: The name of the atom.
+ * NameLength [O]: The length of the name of the atom.
+ *
+ * RETURNS:
+ * Status.
+ *
+ * NOTES:
+ * - NameLength is the length of the string in bytes less the null terminator.
+ * - NameLength is set to the length of the string copied or if it is too
+ * short then it is set to the number of bytes required to store the name,
+ * minus the null terminator.
+ * - PinCount only realy returns 1 or 0, see note in RtlPinAtomInAtomTable.
+ */
+NTSTATUS WINAPI RtlQueryAtomInAtomTable(IN RTL_ATOM_TABLE Table, IN RTL_ATOM Atom,
+ OUT PULONG RefCount, OUT PULONG PinCount, OUT PWSTR AtomName,
+ IN OUT PULONG NameLength)
+{
+ NTSTATUS res;
+ WCHAR full_name[MAX_ATOM_LEN];
+ static WCHAR IntFormat[] = {'#','%','d',0};
+ ULONG Len, intPin, intRef;
+
+ TRACE("(%p, %x, %p, %p, %p, %p)\n", Table, Atom, RefCount, PinCount, AtomName,
+ NameLength);
+
+ if(!Atom) {
+ *NameLength = 0;
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if(Atom < MAXINTATOM) {
+ if(RefCount)
+ *RefCount = 1;
+ if(PinCount)
+ *PinCount = 1;
+ if(AtomName && NameLength) {
+ Len = sprintfW(full_name, IntFormat, Atom);
+ if(Len < *NameLength)
+ strcpyW(AtomName, full_name);
+ *NameLength = Len * sizeof(WCHAR);
+ }
+ TRACE("Found atom with pin: 1, ref: 1, name: %s\n", debugstr_w(full_name));
+ return STATUS_SUCCESS;
+ }
+
+
+ SERVER_START_REQ(query_atom_in_atom_table) {
+ req->table = Table;
+ req->atom = Atom;
+ wine_server_set_reply(req, full_name, sizeof(full_name));
+ res = wine_server_call(req);
+ intPin = reply->pincount;
+ intRef = reply->refcount;
+ if(!res)
+ Len = wine_server_reply_size(reply);
+ } SERVER_END_REQ;
+
+ if(!res) {
+ if(RefCount)
+ *RefCount = intRef;
+ if(PinCount)
+ *PinCount = intPin;
+ full_name[Len / sizeof(WCHAR)] = '\0';
+ if(AtomName && NameLength) {
+ if(Len < *NameLength) strcpyW(AtomName, full_name);
+ else res = STATUS_BUFFER_TOO_SMALL;
+ *NameLength = Len;
+ }
+
+ TRACE("Found atom with pin: %ld, ref: %ld, name: %s\n", intPin, intRef,
+ debugstr_w(full_name));
+ }
+
+ return res;
+}
--- ../cleanwine/server/protocol.def 2003-04-05 08:33:57.000000000 +0200
+++ server/protocol.def 2003-04-07 12:19:38.000000000 +0200
@@ -1478,7 +1478,6 @@
/* Add an atom */
@REQ(add_atom)
- int local; /* is atom in local process table? */
VARARG(name,unicode_str); /* atom name */
@REPLY
atom_t atom; /* resulting atom */
@@ -1488,32 +1487,87 @@
/* Delete an atom */
@REQ(delete_atom)
atom_t atom; /* atom handle */
- int local; /* is atom in local process table? */
@END
/* Find an atom */
@REQ(find_atom)
- int local; /* is atom in local process table? */
VARARG(name,unicode_str); /* atom name */
@REPLY
atom_t atom; /* atom handle */
@END
-/* Get an atom name */
- at REQ(get_atom_name)
- atom_t atom; /* atom handle */
- int local; /* is atom in local process table? */
+/* Get info about a global atom */
+ at REQ(atom_query_information)
+ atom_t atom; /* atom to receive info about */
@REPLY
- int count; /* atom lock count */
- VARARG(name,unicode_str); /* atom name */
+ int refcount; /* The refcount of the atom */
+ int pin; /* Is atom pinned ? */
@END
-/* Init the process atom table */
- at REQ(init_atom_table)
+/* Create an atom table */
+ at REQ(create_atom_table)
int entries; /* number of entries */
+ at REPLY
+ void* table; /* The atom table */
+ at END
+
+
+/* Destroy an atom table */
+ at REQ(destroy_atom_table)
+ void* table; /* The atom table */
+ at END
+
+
+/* Empty an atom table */
+ at REQ(empty_atom_table)
+ void* table; /* The atom table */
+ int delpinned; /* Also delete pinned atoms ? */
+ at END
+
+
+/* Add an atom to an atom table */
+ at REQ(add_atom_to_atom_table)
+ void* table; /* The atom table to add this entry to */
+ VARARG(name,unicode_str); /* atom name */
+ at REPLY
+ atom_t atom; /* The atom */
+ at END
+
+
+/* Delete an atom from an atom table */
+ at REQ(delete_atom_from_atom_table)
+ void* table; /* The atom table to delete this atom from */
+ atom_t atom; /* Atom to delete */
+ at END
+
+
+/* Find an atom in an atom table */
+ at REQ(lookup_atom_in_atom_table)
+ void* table; /* The atom table to lookup these atoms in */
+ VARARG(name,unicode_str); /* The name of the atom to lookup */
+ at REPLY
+ atom_t atom; /* The corrisponding atom */
+ at END
+
+
+/* Pin an atom in an atom table */
+ at REQ(pin_atom_in_atom_table)
+ void* table; /* The table to pin the atom in */
+ atom_t atom; /* The atom to pin */
+ at END
+
+
+/* Query an atom in an atom table */
+ at REQ(query_atom_in_atom_table)
+ void* table; /* The table to query the atom from */
+ atom_t atom; /* The atom to query */
+ at REPLY
+ int refcount; /* The refcount on the atom */
+ int pincount; /* The pincount on the atom */
+ VARARG(name,unicode_str); /* The name of the atom */
@END
--- ../cleanwine/server/atom.c 2003-02-26 14:45:42.000000000 +0200
+++ server/atom.c 2003-04-07 13:18:52.000000000 +0200
@@ -42,12 +42,13 @@
struct atom_entry
{
- struct atom_entry *next; /* hash table list */
- struct atom_entry *prev; /* hash table list */
- int count; /* reference count */
- int hash; /* string hash */
- atom_t atom; /* atom handle */
- WCHAR str[1]; /* atom string */
+ struct atom_entry *next; /* hash table list */
+ struct atom_entry *prev; /* hash table list */
+ int count; /* reference count */
+ int hash; /* string hash */
+ int pincount; /* pin count of the atom */
+ atom_t atom; /* atom handle */
+ WCHAR str[1]; /* atom string */
};
struct atom_table
@@ -184,7 +185,7 @@
{
struct atom_entry *entry = table->handles[i];
if (!entry) continue;
- fprintf( stderr, " %04x: ref=%d hash=%d \"", entry->atom, entry->count, entry->hash );
+ fprintf( stderr, " %04x: ref=%d pin=%d hash=%d \"", entry->atom, entry->count, entry->pincount, entry->hash );
dump_strW( entry->str, strlenW(entry->str), stderr, "\"\"");
fprintf( stderr, "\"\n" );
}
@@ -247,8 +248,9 @@
entry->prev = NULL;
if ((entry->next = table->entries[hash])) entry->next->prev = entry;
table->entries[hash] = entry;
- entry->count = 1;
- entry->hash = hash;
+ entry->count = 1;
+ entry->pincount = 0;
+ entry->hash = hash;
strcpyW( entry->str, str );
}
else free( entry );
@@ -304,7 +306,7 @@
/* add a global atom */
DECL_HANDLER(add_atom)
{
- struct atom_table **table_ptr = req->local ? ¤t->process->atom_table : &global_table;
+ struct atom_table **table_ptr = &global_table;
if (!*table_ptr) *table_ptr = create_table(0);
if (*table_ptr)
@@ -317,7 +319,7 @@
/* delete a global atom */
DECL_HANDLER(delete_atom)
{
- delete_atom( req->local ? current->process->atom_table : global_table, req->atom );
+ delete_atom( global_table, req->atom );
}
/* find a global atom */
@@ -325,29 +327,91 @@
{
const WCHAR *name = copy_request_name();
if (name)
- reply->atom = find_atom( req->local ? current->process->atom_table : global_table, name );
+ reply->atom = find_atom( global_table, name );
}
-/* get global atom name */
-DECL_HANDLER(get_atom_name)
+/* Get info about a global atom */
+DECL_HANDLER(atom_query_information)
{
struct atom_entry *entry;
size_t len = 0;
- reply->count = -1;
- if ((entry = get_atom_entry( req->local ? current->process->atom_table : global_table,
- req->atom )))
+ if ((entry = get_atom_entry( global_table, req->atom )))
{
- reply->count = entry->count;
+ reply->refcount = entry->count;
+ reply->pin = entry->pincount;
len = strlenW( entry->str ) * sizeof(WCHAR);
if (len <= get_reply_max_size()) set_reply_data( entry->str, len );
else set_error( STATUS_BUFFER_OVERFLOW );
}
}
-/* init the process atom table */
-DECL_HANDLER(init_atom_table)
+/* Create an atom table */
+DECL_HANDLER(create_atom_table)
{
- if (!current->process->atom_table)
- current->process->atom_table = create_table( req->entries );
+ void *table = create_table( req->entries );
+ if (table)
+ reply->table = table;
+}
+
+/* Destroy an atom table */
+DECL_HANDLER(destroy_atom_table)
+{
+ release_object( req->table );
+}
+
+/* Empty an atom table */
+DECL_HANDLER(empty_atom_table)
+{
+ int i;
+ struct atom_entry *entry;
+ struct atom_table *table = req->table;
+
+ for(i = 0; i <= table->last; i++)
+ {
+ entry = table->handles[i];
+ if (entry && (!entry->pincount || req->delpinned))
+ delete_atom( req->table, i + MIN_STR_ATOM );
+ }
+}
+
+DECL_HANDLER(add_atom_to_atom_table)
+{
+ const WCHAR *name = copy_request_name();
+ if (name) reply->atom = add_atom( req->table, name );
+}
+
+DECL_HANDLER(delete_atom_from_atom_table)
+{
+ struct atom_entry *entry = get_atom_entry( req->table, req->atom );
+
+ if (!entry->pincount) delete_atom( req->table, req->atom );
+ else set_error( STATUS_WAS_LOCKED );
+}
+
+DECL_HANDLER(lookup_atom_in_atom_table)
+{
+ const WCHAR *name = copy_request_name();
+ if (name)
+ reply->atom = find_atom( req->table, name );
+}
+
+DECL_HANDLER(pin_atom_in_atom_table)
+{
+ struct atom_entry *entry = get_atom_entry( req->table, req->atom );
+ if (entry && !entry->pincount)
+ entry->pincount++;
+}
+
+DECL_HANDLER(query_atom_in_atom_table)
+{
+ struct atom_entry *entry = get_atom_entry( req->table, req->atom );
+ int len;
+ if (entry) {
+ len = strlenW( entry->str ) * sizeof(WCHAR);
+ reply->refcount = entry->count;
+ reply->pincount = entry->pincount;
+ if (len <= get_reply_max_size()) set_reply_data( entry->str, len );
+ else set_error( STATUS_OBJECT_NAME_NOT_FOUND );
+ }
}
--- ../cleanwine/memory/atom.c 2002-10-04 19:45:00.000000000 +0200
+++ memory/atom.c 2003-04-07 13:52:07.000000000 +0200
@@ -36,6 +36,7 @@
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
+#include "winternl.h"
#include "wine/server.h"
#include "wine/unicode.h"
@@ -69,6 +70,10 @@
} ATOMTABLE;
+/* The local atom table */
+static RTL_ATOM_TABLE local_table = NULL;
+
+
/***********************************************************************
* ATOM_GetTable
*
@@ -142,33 +147,6 @@
/***********************************************************************
- * ATOM_IsIntAtomW
- */
-static BOOL ATOM_IsIntAtomW(LPCWSTR atomstr,WORD *atomid)
-{
- UINT atom = 0;
- if (!HIWORD(atomstr)) atom = LOWORD(atomstr);
- else
- {
- if (*atomstr++ != '#') return FALSE;
- while (*atomstr >= '0' && *atomstr <= '9')
- {
- atom = atom * 10 + *atomstr - '0';
- atomstr++;
- }
- if (*atomstr) return FALSE;
- }
- if (atom >= MAXINTATOM)
- {
- SetLastError( ERROR_INVALID_PARAMETER );
- atom = 0;
- }
- *atomid = atom;
- return TRUE;
-}
-
-
-/***********************************************************************
* ATOM_MakePtr
*
* Make an ATOMENTRY pointer from a handle (obtained from GetAtomHandle()).
@@ -386,43 +364,29 @@
/***********************************************************************
* InitAtomTable (KERNEL32.@)
+ *
+ * Initialises the local atom table.
+ *
+ * PARAMS:
+ * entries [I]: Number of has buckets to allocate. If this parameter is 0
+ * then the default of 37 will be used.
+ *
+ * RETURNS:
+ * True: Success
+ * False: Failure
+ *
+ * NOTES:
+ * This function need not be called before any local atom management has taken
+ * place.
*/
BOOL WINAPI InitAtomTable( DWORD entries )
{
- BOOL ret;
- SERVER_START_REQ( init_atom_table )
- {
- req->entries = entries;
- ret = !wine_server_call_err( req );
- }
- SERVER_END_REQ;
- return ret;
-}
-
-
-static ATOM ATOM_AddAtomA( LPCSTR str, BOOL local )
-{
- ATOM atom = 0;
- if (!ATOM_IsIntAtomA( 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 );
- return 0;
- }
- SERVER_START_REQ( add_atom )
- {
- wine_server_add_data( req, buffer, len * sizeof(WCHAR) );
- req->local = local;
- if (!wine_server_call_err(req)) atom = reply->atom;
- }
- SERVER_END_REQ;
+ NTSTATUS res = STATUS_SUCCESS;
+ if (!local_table) {
+ if ((res = RtlCreateAtomTable( entries, &local_table )))
+ SetLastError( RtlNtStatusToDosError(res) );
}
- TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugstr_a(str), atom );
- return atom;
+ return !res;
}
@@ -438,13 +402,29 @@
*/
ATOM WINAPI GlobalAddAtomA( LPCSTR str /* [in] Pointer to string to add */ )
{
- return ATOM_AddAtomA( str, FALSE );
+ UNICODE_STRING wstr;
+ ATOM atom;
+
+ if(HIWORD(str))
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz( &wstr, str )) {
+ SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+ return 0;
+ }
+
+ atom = GlobalAddAtomW( wstr.Buffer );
+ RtlFreeUnicodeString( &wstr );
+ }
+ else
+ atom = GlobalAddAtomW( (LPCWSTR)str );
+
+ return atom;
}
/***********************************************************************
* AddAtomA (KERNEL32.@)
- * Adds a string to the atom table and returns the atom identifying the
+ * Adds a string to the local atom table and returns the atom identifying the
* string.
*
* RETURNS
@@ -453,31 +433,23 @@
*/
ATOM WINAPI AddAtomA( LPCSTR str /* [in] Pointer to string to add */ )
{
- return ATOM_AddAtomA( str, TRUE );
-}
+ UNICODE_STRING wstr;
+ ATOM atom;
-
-static ATOM ATOM_AddAtomW( LPCWSTR str, BOOL local )
-{
- ATOM atom = 0;
- if (!ATOM_IsIntAtomW( str, &atom ))
+ if(HIWORD(str))
{
- DWORD len = strlenW(str);
- if (len > MAX_ATOM_LEN)
- {
- SetLastError( ERROR_INVALID_PARAMETER );
+ if (!RtlCreateUnicodeStringFromAsciiz( &wstr, str )) {
+ SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return 0;
}
- SERVER_START_REQ( add_atom )
- {
- req->local = local;
- wine_server_add_data( req, str, len * sizeof(WCHAR) );
- if (!wine_server_call_err(req)) atom = reply->atom;
- }
- SERVER_END_REQ;
+
+ atom = AddAtomW( wstr.Buffer );
+ RtlFreeUnicodeString( &wstr );
}
- TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugstr_w(str), atom );
+ else
+ atom = AddAtomW( (LPCWSTR)str );
return atom;
+
}
@@ -486,7 +458,17 @@
*/
ATOM WINAPI GlobalAddAtomW( LPCWSTR str )
{
- return ATOM_AddAtomW( str, FALSE );
+ NTSTATUS res;
+ ATOM atom;
+
+ /* If a 0 atom is passed in, then we shouldn't set last error */
+ if (!str)
+ return 0;
+
+ if ((res = NtAddAtom( str, &atom )))
+ SetLastError( RtlNtStatusToDosError(res) );
+
+ return res ? 0 : atom;
}
@@ -495,24 +477,15 @@
*/
ATOM WINAPI AddAtomW( LPCWSTR str )
{
- return ATOM_AddAtomW( str, TRUE );
-}
+ NTSTATUS res;
+ ATOM atom;
+ if (!local_table || !InitAtomTable(0))
+ return 0;
-static ATOM ATOM_DeleteAtom( ATOM atom, BOOL local)
-{
- TRACE( "(%s) %x\n", local ? "local" : "global", atom );
- if (atom >= MAXINTATOM)
- {
- SERVER_START_REQ( delete_atom )
- {
- req->atom = atom;
- req->local = local;
- wine_server_call_err( req );
- }
- SERVER_END_REQ;
- }
- return 0;
+ if ((res = RtlAddAtomToAtomTable(local_table, str, &atom)))
+ SetLastError( RtlNtStatusToDosError(res) );
+ return atom;
}
@@ -527,7 +500,12 @@
*/
ATOM WINAPI GlobalDeleteAtom( ATOM atom /* [in] Atom to delete */ )
{
- return ATOM_DeleteAtom( atom, FALSE);
+ NTSTATUS res;
+
+ if ((res = NtDeleteAtom(atom)))
+ SetLastError( RtlNtStatusToDosError(res) );
+
+ return res ? atom : 0;
}
@@ -542,33 +520,15 @@
*/
ATOM WINAPI DeleteAtom( ATOM atom /* [in] Atom to delete */ )
{
- return ATOM_DeleteAtom( atom, TRUE );
-}
+ NTSTATUS res;
+ if (!local_table || !InitAtomTable(0))
+ return atom;
-static ATOM ATOM_FindAtomA( LPCSTR str, BOOL local )
-{
- ATOM atom = 0;
- if (!ATOM_IsIntAtomA( str, &atom ))
- {
- WCHAR buffer[MAX_ATOM_LEN];
+ if((res = RtlDeleteAtomFromAtomTable(local_table, atom)))
+ SetLastError( RtlNtStatusToDosError(res) );
- DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), buffer, MAX_ATOM_LEN );
- if (!len)
- {
- SetLastError( ERROR_INVALID_PARAMETER );
- return 0;
- }
- SERVER_START_REQ( find_atom )
- {
- req->local = local;
- wine_server_add_data( req, buffer, len * sizeof(WCHAR) );
- if (!wine_server_call_err(req)) atom = reply->atom;
- }
- SERVER_END_REQ;
- }
- TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugstr_a(str), atom );
- return atom;
+ return res ? atom : 0;
}
@@ -584,7 +544,17 @@
*/
ATOM WINAPI GlobalFindAtomA( LPCSTR str /* [in] Pointer to string to search for */ )
{
- return ATOM_FindAtomA( str, FALSE );
+ UNICODE_STRING wstr;
+ ATOM atom;
+
+ if (!RtlCreateUnicodeStringFromAsciiz( &wstr, str )) {
+ SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+ return 0;
+ }
+
+ atom = GlobalFindAtomW( wstr.Buffer );
+ RtlFreeUnicodeString( &wstr );
+ return atom;
}
/***********************************************************************
@@ -598,30 +568,16 @@
*/
ATOM WINAPI FindAtomA( LPCSTR str /* [in] Pointer to string to find */ )
{
- return ATOM_FindAtomA( str, TRUE );
-}
-
+ UNICODE_STRING wstr;
+ ATOM atom;
-static ATOM ATOM_FindAtomW( LPCWSTR str, BOOL local )
-{
- ATOM atom = 0;
- if (!ATOM_IsIntAtomW( str, &atom ))
- {
- DWORD len = strlenW(str);
- if (len > MAX_ATOM_LEN)
- {
- SetLastError( ERROR_INVALID_PARAMETER );
- return 0;
- }
- SERVER_START_REQ( find_atom )
- {
- wine_server_add_data( req, str, len * sizeof(WCHAR) );
- req->local = local;
- if (!wine_server_call_err( req )) atom = reply->atom;
- }
- SERVER_END_REQ;
+ if (!RtlCreateUnicodeStringFromAsciiz( &wstr, str )) {
+ SetLastError( ERROR_NOT_ENOUGH_MEMORY );
+ return 0;
}
- TRACE( "(%s) %s -> %x\n", local ? "local" : "global", debugstr_w(str), atom );
+
+ atom = FindAtomW( wstr.Buffer );
+ RtlFreeUnicodeString( &wstr );
return atom;
}
@@ -631,7 +587,13 @@
*/
ATOM WINAPI GlobalFindAtomW( LPCWSTR str )
{
- return ATOM_FindAtomW( str, FALSE );
+ NTSTATUS res;
+ ATOM atom;
+
+ if ((res = NtFindAtom( str, &atom )))
+ SetLastError( RtlNtStatusToDosError(res) );
+
+ return res ? 0 : atom;
}
@@ -640,60 +602,16 @@
*/
ATOM WINAPI FindAtomW( LPCWSTR str )
{
- return ATOM_FindAtomW( str, TRUE );
-}
-
-
-static UINT ATOM_GetAtomNameA( ATOM atom, LPSTR buffer, INT count, BOOL local )
-{
- INT len;
+ NTSTATUS res;
+ ATOM atom;
- if (count <= 0)
- {
- SetLastError( ERROR_MORE_DATA );
- return 0;
- }
- if (atom < MAXINTATOM)
- {
- char name[8];
- if (!atom)
- {
- SetLastError( ERROR_INVALID_PARAMETER );
- return 0;
- }
- len = sprintf( name, "#%d", atom );
- lstrcpynA( buffer, name, count );
- }
- else
- {
- WCHAR full_name[MAX_ATOM_LEN];
+ if (!local_table || !InitAtomTable(0))
+ return atom;
- len = 0;
- SERVER_START_REQ( get_atom_name )
- {
- req->atom = atom;
- req->local = local;
- wine_server_set_reply( req, full_name, sizeof(full_name) );
- if (!wine_server_call_err( req ))
- {
- len = WideCharToMultiByte( CP_ACP, 0, full_name,
- wine_server_reply_size(reply) / sizeof(WCHAR),
- buffer, count - 1, NULL, NULL );
- if (!len) len = count; /* overflow */
- else buffer[len] = 0;
- }
- }
- SERVER_END_REQ;
- }
+ if ((res = RtlLookupAtomInAtomTable( local_table, str, &atom )))
+ SetLastError( RtlNtStatusToDosError(res) );
- if (len && count <= len)
- {
- SetLastError( ERROR_MORE_DATA );
- buffer[count-1] = 0;
- return 0;
- }
- TRACE( "(%s) %x -> %s\n", local ? "local" : "global", atom, debugstr_a(buffer) );
- return len;
+ return res ? 0 : atom;
}
@@ -711,7 +629,27 @@
LPSTR buffer, /* [out] Pointer to buffer for atom string */
INT count ) /* [in] Size of buffer */
{
- return ATOM_GetAtomNameA( atom, buffer, count, FALSE );
+ NTSTATUS res;
+ PATOM_BASIC_INFORMATION info;
+ ULONG len = MAX_ATOM_LEN * sizeof(WCHAR) + sizeof(ATOM_BASIC_INFORMATION);
+
+ /* Since WideCharToMultibyte returns to number of bytes required if dstlen
+ * is 0, we check for it here to avoid returning a wrong value */
+ if (!count)
+ return 0;
+
+ info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len );
+
+ if ((res = NtQueryInformationAtom( atom, AtomBasicInformation, info, len, &len ))) {
+ SetLastError( RtlNtStatusToDosError(res) );
+ HeapFree( GetProcessHeap(), 0, info );
+ return 0;
+ }
+
+ len = WideCharToMultiByte( CP_ACP, 0, info->Name, -1, buffer, count, NULL, NULL ) - 1;
+ TRACE("Returning %ld\n", len);
+ HeapFree( GetProcessHeap(), 0, info );
+ return len;
}
@@ -728,54 +666,19 @@
LPSTR buffer, /* [out] Pointer to string for atom string */
INT count) /* [in] Size of buffer */
{
- return ATOM_GetAtomNameA( atom, buffer, count, TRUE );
-}
-
+ NTSTATUS res;
+ WCHAR full_name[MAX_ATOM_LEN];
+ ULONG len = sizeof(WCHAR) * MAX_ATOM_LEN;
-static UINT ATOM_GetAtomNameW( ATOM atom, LPWSTR buffer, INT count, BOOL local )
-{
- INT len;
+ if (!count)
+ return 0;
- if (count <= 0)
- {
- SetLastError( ERROR_MORE_DATA );
+ if ((res = RtlQueryAtomInAtomTable( local_table, atom, NULL, NULL, full_name, &len))) {
+ SetLastError( RtlNtStatusToDosError(res) );
return 0;
}
- if (atom < MAXINTATOM)
- {
- char name[8];
- if (!atom)
- {
- SetLastError( ERROR_INVALID_PARAMETER );
- return 0;
- }
- sprintf( name, "#%d", atom );
- len = MultiByteToWideChar( CP_ACP, 0, name, -1, buffer, count );
- if (!len) buffer[count-1] = 0; /* overflow */
- }
- else
- {
- WCHAR full_name[MAX_ATOM_LEN];
- len = 0;
- SERVER_START_REQ( get_atom_name )
- {
- req->atom = atom;
- req->local = local;
- wine_server_set_reply( req, full_name, sizeof(full_name) );
- if (!wine_server_call_err( req ))
- {
- len = wine_server_reply_size(reply) / sizeof(WCHAR);
- if (count > len) count = len + 1;
- memcpy( buffer, full_name, (count-1) * sizeof(WCHAR) );
- buffer[count-1] = 0;
- }
- }
- SERVER_END_REQ;
- if (!len) return 0;
- }
- TRACE( "(%s) %x -> %s\n", local ? "local" : "global", atom, debugstr_w(buffer) );
- return len;
+ return WideCharToMultiByte( CP_ACP, 0, full_name, -1, buffer, count, NULL, NULL );
}
@@ -784,7 +687,26 @@
*/
UINT WINAPI GlobalGetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
{
- return ATOM_GetAtomNameW( atom, buffer, count, FALSE);
+ NTSTATUS res;
+ PATOM_BASIC_INFORMATION info;
+ ULONG len = MAX_ATOM_LEN * sizeof(WCHAR) + sizeof(ATOM_BASIC_INFORMATION);
+
+ info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len );
+
+ if ((res = NtQueryInformationAtom( atom, AtomBasicInformation, info, len, &len ))) {
+ SetLastError( RtlNtStatusToDosError(res) );
+ HeapFree( GetProcessHeap(), 0, info );
+ return 0;
+ }
+ if (info->NameLen > count) {
+ SetLastError( ERROR_BUFFER_OVERFLOW );
+ HeapFree( GetProcessHeap(), 0, info );
+ return 0;
+ }
+ strcpyW(buffer, info->Name);
+ len = info->NameLen;
+ HeapFree( GetProcessHeap(), 0, info );
+ return len;
}
@@ -793,5 +715,20 @@
*/
UINT WINAPI GetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
{
- return ATOM_GetAtomNameW( atom, buffer, count, TRUE );
+ NTSTATUS res;
+ WCHAR full_name[MAX_ATOM_LEN];
+ ULONG len = sizeof(WCHAR) * MAX_ATOM_LEN;
+
+ if ((res = RtlQueryAtomInAtomTable( local_table, atom, NULL, NULL, full_name, &len))) {
+ SetLastError( RtlNtStatusToDosError(res) );
+ return 0;
+ }
+
+ if (len > count) {
+ SetLastError( ERROR_BUFFER_OVERFLOW );
+ return 0;
+ }
+ strcpyW( buffer, full_name );
+
+ return len;
}
More information about the wine-patches
mailing list