blob: 9682fb4705d03344446fb363f86798d18fa5a2ae [file] [log] [blame]
Alexandre Julliard5f721f81994-01-04 20:14:34 +00001/*
2 * Atom table functions
3 *
Alexandre Julliarde2abbb11995-03-19 17:39:39 +00004 * Copyright 1993, 1994, 1995 Alexandre Julliard
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00005 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
Jonathan Ernst360a3f92006-05-18 14:49:52 +020018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Alexandre Julliard5f721f81994-01-04 20:14:34 +000019 */
20
Patrik Stridvallbc38d6b2001-07-20 18:00:00 +000021#include "config.h"
Patrik Stridvall51e6c0c2002-08-31 19:04:14 +000022#include "wine/port.h"
Patrik Stridvallbc38d6b2001-07-20 18:00:00 +000023
Alexandre Julliard5f721f81994-01-04 20:14:34 +000024#include <stdlib.h>
Alexandre Julliarde37c6e12003-09-05 23:08:26 +000025#include <stdarg.h>
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000026#include <stdio.h>
Alexandre Julliard5f721f81994-01-04 20:14:34 +000027#include <string.h>
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000028#include <ctype.h>
Alexandre Julliard5f721f81994-01-04 20:14:34 +000029
Jeremy Whited3e22d92000-02-10 19:03:02 +000030#include "windef.h"
Francois Gouget541ff5f2001-10-15 17:49:23 +000031#include "winbase.h"
Alexandre Julliardb849d792000-02-13 13:56:13 +000032#include "winerror.h"
Eric Pouech289889c2005-10-29 12:37:42 +000033#include "winternl.h"
Patrik Stridvallbc38d6b2001-07-20 18:00:00 +000034
Marcus Meissner6c2eae22005-08-19 15:20:06 +000035#include "wine/exception.h"
Patrik Stridvallbc38d6b2001-07-20 18:00:00 +000036#include "wine/unicode.h"
Alexandre Julliard55b51ea2003-11-13 21:04:01 +000037#include "kernel_private.h"
Patrik Stridvallbc38d6b2001-07-20 18:00:00 +000038
Eric Pouech78d096c2005-02-03 16:58:21 +000039#define MAX_ATOM_LEN 255
Michael Stefaniuc3f37e332010-02-10 11:43:37 +010040#define IS_INTATOM(x) (((ULONG_PTR)(x) >> 16) == 0)
Alexandre Julliard5f721f81994-01-04 20:14:34 +000041
Eric Pouech289889c2005-10-29 12:37:42 +000042/******************************************************************
43 * get_local_table
44 *
45 * Returns the local atom table for this process (and create it if doesn't
46 * exist yet)
47 */
48static RTL_ATOM_TABLE get_local_table(DWORD entries)
Eric Poueche6267362005-05-10 15:15:50 +000049{
Eric Pouech289889c2005-10-29 12:37:42 +000050 static RTL_ATOM_TABLE local_table;
Eric Poueche6267362005-05-10 15:15:50 +000051
52 if (!local_table)
53 {
Eric Pouech289889c2005-10-29 12:37:42 +000054 NTSTATUS status;
55 RTL_ATOM_TABLE table = NULL;
Eric Poueche6267362005-05-10 15:15:50 +000056
Eric Pouech289889c2005-10-29 12:37:42 +000057 if ((status = RtlCreateAtomTable( entries, &table )))
Eric Poueche6267362005-05-10 15:15:50 +000058 SetLastError( RtlNtStatusToDosError( status ) );
59 else if (InterlockedCompareExchangePointer((void*)&local_table, table, NULL) != NULL)
Eric Pouech289889c2005-10-29 12:37:42 +000060 RtlDestroyAtomTable( table );
Eric Poueche6267362005-05-10 15:15:50 +000061 }
Eric Pouech289889c2005-10-29 12:37:42 +000062
Eric Poueche6267362005-05-10 15:15:50 +000063 return local_table;
64}
65
Alexandre Julliardb849d792000-02-13 13:56:13 +000066
67/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +000068 * InitAtomTable (KERNEL32.@)
Jon Griffiths4c1fa162003-10-01 03:20:21 +000069 *
Nikolay Sivovdde69d62015-05-08 18:05:02 +030070 * Initialise local atom table.
Jon Griffiths4c1fa162003-10-01 03:20:21 +000071 *
72 * PARAMS
73 * entries [I] The number of entries to reserve in the table.
74 *
75 * RETURNS
76 * Success: TRUE.
77 * Failure: FALSE.
Alexandre Julliard5f721f81994-01-04 20:14:34 +000078 */
Turchanov Sergei43a27e32000-05-30 20:32:06 +000079BOOL WINAPI InitAtomTable( DWORD entries )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +000080{
Michael Stefaniuc97512d72012-07-31 11:34:54 +020081 return get_local_table( entries ) != 0;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +000082}
83
Eric Pouech289889c2005-10-29 12:37:42 +000084/******************************************************************
85 * check_integral_atom
86 *
87 * Check if a string (ANSI or UNICODE) is in fact an integral atom
88 * (but doesn't check the "#1234" form)
89 */
90static inline BOOL check_integral_atom( const void* ptr, ATOM* patom)
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +000091{
Michael Stefaniuc3f37e332010-02-10 11:43:37 +010092 if (!IS_INTATOM( ptr )) return FALSE;
Eric Pouech289889c2005-10-29 12:37:42 +000093 if ((*patom = LOWORD( ptr )) >= MAXINTATOM)
Turchanov Sergei43a27e32000-05-30 20:32:06 +000094 {
Eric Pouech289889c2005-10-29 12:37:42 +000095 SetLastError( ERROR_INVALID_PARAMETER );
96 *patom = 0;
Turchanov Sergei43a27e32000-05-30 20:32:06 +000097 }
Eric Pouech289889c2005-10-29 12:37:42 +000098 return TRUE;
Alexandre Julliard5f721f81994-01-04 20:14:34 +000099}
100
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000101/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000102 * GlobalAddAtomA (KERNEL32.@)
Alexandre Julliardb849d792000-02-13 13:56:13 +0000103 *
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000104 * Add a character string to the global atom table and return a unique
105 * value identifying it.
Alexandre Julliard54c27111998-03-29 19:44:57 +0000106 *
107 * RETURNS
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000108 * Success: The atom allocated to str.
109 * Failure: 0.
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000110 */
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000111ATOM WINAPI GlobalAddAtomA( LPCSTR str /* [in] String to add */ )
Alexandre Julliardb849d792000-02-13 13:56:13 +0000112{
Eric Pouech289889c2005-10-29 12:37:42 +0000113 ATOM atom = 0;
Marcus Meissner6c2eae22005-08-19 15:20:06 +0000114 __TRY
115 {
Eric Pouech289889c2005-10-29 12:37:42 +0000116 if (!check_integral_atom( str, &atom ))
117 {
118 WCHAR buffer[MAX_ATOM_LEN];
119 DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), buffer, MAX_ATOM_LEN );
120 if (!len) SetLastError( ERROR_INVALID_PARAMETER );
121 else
122 {
123 NTSTATUS status = NtAddAtom( buffer, len * sizeof(WCHAR), &atom );
124 if (status)
125 {
126 SetLastError( RtlNtStatusToDosError( status ) );
127 atom = 0;
128 }
129 }
130 }
Marcus Meissner6c2eae22005-08-19 15:20:06 +0000131 }
Alexandre Julliardae964ac2005-12-16 17:17:57 +0100132 __EXCEPT_PAGE_FAULT
Marcus Meissner6c2eae22005-08-19 15:20:06 +0000133 {
134 SetLastError( ERROR_INVALID_PARAMETER );
Eric Pouech289889c2005-10-29 12:37:42 +0000135 atom = 0;
Marcus Meissner6c2eae22005-08-19 15:20:06 +0000136 }
137 __ENDTRY
Eric Pouech289889c2005-10-29 12:37:42 +0000138 return atom;
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000139}
140
141
142/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000143 * AddAtomA (KERNEL32.@)
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000144 *
Nikolay Sivovdde69d62015-05-08 18:05:02 +0300145 * Add a character string to local atom table and return a unique
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000146 * value identifying it.
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000147 *
148 * RETURNS
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000149 * Success: The atom allocated to str.
150 * Failure: 0.
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000151 */
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000152ATOM WINAPI AddAtomA( LPCSTR str /* [in] String to add */ )
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000153{
Alexandre Julliardb849d792000-02-13 13:56:13 +0000154 ATOM atom = 0;
Eric Pouech289889c2005-10-29 12:37:42 +0000155
156 if (!check_integral_atom( str, &atom ))
Alexandre Julliardb849d792000-02-13 13:56:13 +0000157 {
Eric Pouech289889c2005-10-29 12:37:42 +0000158 WCHAR buffer[MAX_ATOM_LEN + 1];
159 DWORD len;
160 RTL_ATOM_TABLE table;
161
162 len = MultiByteToWideChar( CP_ACP, 0, str, -1, buffer, MAX_ATOM_LEN + 1 );
163 if (!len) SetLastError( ERROR_INVALID_PARAMETER );
164 else if ((table = get_local_table( 0 )))
Alexandre Julliard9c2370b2000-08-30 00:00:48 +0000165 {
Eric Pouech289889c2005-10-29 12:37:42 +0000166 NTSTATUS status = RtlAddAtomToAtomTable( table, buffer, &atom );
167 if (status)
168 {
169 SetLastError( RtlNtStatusToDosError( status ) );
170 atom = 0;
171 }
Alexandre Julliard9c2370b2000-08-30 00:00:48 +0000172 }
Alexandre Julliardb849d792000-02-13 13:56:13 +0000173 }
Alexandre Julliardb849d792000-02-13 13:56:13 +0000174 return atom;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000175}
176
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000177/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000178 * GlobalAddAtomW (KERNEL32.@)
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000179 *
180 * Unicode version of GlobalAddAtomA.
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000181 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000182ATOM WINAPI GlobalAddAtomW( LPCWSTR str )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000183{
Eric Pouech289889c2005-10-29 12:37:42 +0000184 ATOM atom = 0;
185 NTSTATUS status;
186
187 if (!check_integral_atom( str, &atom ) &&
188 (status = NtAddAtom( str, strlenW( str ) * sizeof(WCHAR), &atom )))
189 {
190 SetLastError( RtlNtStatusToDosError( status ) );
191 atom = 0;
192 }
193 return atom;
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000194}
195
196
197/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000198 * AddAtomW (KERNEL32.@)
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000199 *
200 * Unicode version of AddAtomA.
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000201 */
202ATOM WINAPI AddAtomW( LPCWSTR str )
203{
Eric Pouech289889c2005-10-29 12:37:42 +0000204 ATOM atom = 0;
205 RTL_ATOM_TABLE table;
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000206
Eric Pouech289889c2005-10-29 12:37:42 +0000207 if (!check_integral_atom( str, &atom ) && (table = get_local_table( 0 )))
Alexandre Julliardb849d792000-02-13 13:56:13 +0000208 {
Eric Pouech289889c2005-10-29 12:37:42 +0000209 NTSTATUS status = RtlAddAtomToAtomTable( table, str, &atom );
210 if (status)
Alexandre Julliard9c2370b2000-08-30 00:00:48 +0000211 {
Eric Pouech289889c2005-10-29 12:37:42 +0000212 SetLastError( RtlNtStatusToDosError( status ) );
213 atom = 0;
Alexandre Julliard9c2370b2000-08-30 00:00:48 +0000214 }
Alexandre Julliardb849d792000-02-13 13:56:13 +0000215 }
Eric Pouech289889c2005-10-29 12:37:42 +0000216 return atom;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000217}
218
219
220/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000221 * GlobalDeleteAtom (KERNEL32.@)
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000222 *
223 * Decrement the reference count of a string atom. If the count is
Alexandre Julliard54c27111998-03-29 19:44:57 +0000224 * zero, the string associated with the atom is removed from the table.
225 *
226 * RETURNS
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000227 * Success: 0.
228 * Failure: atom.
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000229 */
Alexandre Julliardb849d792000-02-13 13:56:13 +0000230ATOM WINAPI GlobalDeleteAtom( ATOM atom /* [in] Atom to delete */ )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000231{
Eric Pouech289889c2005-10-29 12:37:42 +0000232 if (atom >= MAXINTATOM)
233 {
234 NTSTATUS status = NtDeleteAtom( atom );
235 if (status)
236 {
237 SetLastError( RtlNtStatusToDosError( status ) );
238 return atom;
239 }
240 }
241 return 0;
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000242}
243
244
245/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000246 * DeleteAtom (KERNEL32.@)
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000247 *
248 * Decrement the reference count of a string atom. If the count becomes
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000249 * zero, the string associated with the atom is removed from the table.
250 *
251 * RETURNS
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000252 * Success: 0.
253 * Failure: atom
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000254 */
255ATOM WINAPI DeleteAtom( ATOM atom /* [in] Atom to delete */ )
256{
Eric Pouech289889c2005-10-29 12:37:42 +0000257 NTSTATUS status;
258 RTL_ATOM_TABLE table;
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000259
Eric Pouech289889c2005-10-29 12:37:42 +0000260 if (atom >= MAXINTATOM)
Alexandre Julliardb849d792000-02-13 13:56:13 +0000261 {
Eric Pouech289889c2005-10-29 12:37:42 +0000262 if (!(table = get_local_table( 0 ))) return atom;
263 status = RtlDeleteAtomFromAtomTable( table, atom );
264 if (status)
Alexandre Julliard9c2370b2000-08-30 00:00:48 +0000265 {
Eric Pouech289889c2005-10-29 12:37:42 +0000266 SetLastError( RtlNtStatusToDosError( status ) );
267 return atom;
Alexandre Julliard9c2370b2000-08-30 00:00:48 +0000268 }
Alexandre Julliardb849d792000-02-13 13:56:13 +0000269 }
Eric Pouech289889c2005-10-29 12:37:42 +0000270 return 0;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000271}
272
273
274/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000275 * GlobalFindAtomA (KERNEL32.@)
Alexandre Julliardb849d792000-02-13 13:56:13 +0000276 *
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000277 * Get the atom associated with a string.
Alexandre Julliard54c27111998-03-29 19:44:57 +0000278 *
279 * RETURNS
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000280 * Success: The associated atom.
281 * Failure: 0.
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000282 */
Alexandre Julliardb849d792000-02-13 13:56:13 +0000283ATOM WINAPI GlobalFindAtomA( LPCSTR str /* [in] Pointer to string to search for */ )
284{
Eric Pouech289889c2005-10-29 12:37:42 +0000285 ATOM atom = 0;
286
287 if (!check_integral_atom( str, &atom ))
288 {
289 WCHAR buffer[MAX_ATOM_LEN];
290 DWORD len = MultiByteToWideChar( CP_ACP, 0, str, strlen(str), buffer, MAX_ATOM_LEN );
291
292 if (!len) SetLastError( ERROR_INVALID_PARAMETER );
293 else
294 {
295 NTSTATUS status = NtFindAtom( buffer, len * sizeof(WCHAR), &atom );
296 if (status)
297 {
298 SetLastError( RtlNtStatusToDosError( status ) );
299 atom = 0;
300 }
301 }
302 }
303 return atom;
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000304}
305
306/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000307 * FindAtomA (KERNEL32.@)
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000308 *
309 * Get the atom associated with a string.
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000310 *
311 * RETURNS
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000312 * Success: The associated atom.
313 * Failure: 0.
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000314 */
315ATOM WINAPI FindAtomA( LPCSTR str /* [in] Pointer to string to find */ )
316{
Alexandre Julliardb849d792000-02-13 13:56:13 +0000317 ATOM atom = 0;
Eric Pouech289889c2005-10-29 12:37:42 +0000318
319 if (!check_integral_atom( str, &atom ))
Alexandre Julliardb849d792000-02-13 13:56:13 +0000320 {
Eric Pouech289889c2005-10-29 12:37:42 +0000321 WCHAR buffer[MAX_ATOM_LEN + 1];
322 DWORD len;
323 RTL_ATOM_TABLE table;
324
325 len = MultiByteToWideChar( CP_ACP, 0, str, -1, buffer, MAX_ATOM_LEN + 1 );
326 if (!len) SetLastError( ERROR_INVALID_PARAMETER );
327 else if ((table = get_local_table( 0 )))
Alexandre Julliard9c2370b2000-08-30 00:00:48 +0000328 {
Eric Pouech289889c2005-10-29 12:37:42 +0000329 NTSTATUS status = RtlLookupAtomInAtomTable( table, buffer, &atom );
330 if (status)
331 {
332 SetLastError( RtlNtStatusToDosError( status ) );
333 atom = 0;
334 }
Alexandre Julliard9c2370b2000-08-30 00:00:48 +0000335 }
Alexandre Julliardb849d792000-02-13 13:56:13 +0000336 }
Alexandre Julliardb849d792000-02-13 13:56:13 +0000337 return atom;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000338}
339
340
341/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000342 * GlobalFindAtomW (KERNEL32.@)
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000343 *
344 * Unicode version of GlobalFindAtomA.
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000345 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000346ATOM WINAPI GlobalFindAtomW( LPCWSTR str )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000347{
Eric Pouech289889c2005-10-29 12:37:42 +0000348 ATOM atom = 0;
349
350 if (!check_integral_atom( str, &atom ))
351 {
352 NTSTATUS status = NtFindAtom( str, strlenW( str ) * sizeof(WCHAR), &atom );
353 if (status)
354 {
355 SetLastError( RtlNtStatusToDosError( status ) );
356 atom = 0;
357 }
358 }
359 return atom;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000360}
361
362
363/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000364 * FindAtomW (KERNEL32.@)
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000365 *
366 * Unicode version of FindAtomA.
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000367 */
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000368ATOM WINAPI FindAtomW( LPCWSTR str )
369{
Eric Pouech289889c2005-10-29 12:37:42 +0000370 ATOM atom = 0;
371 NTSTATUS status;
372 RTL_ATOM_TABLE table;
373
374 if ((table = get_local_table( 0 )))
375 {
376 status = RtlLookupAtomInAtomTable( table, str, &atom );
377 if (status)
378 {
379 SetLastError( RtlNtStatusToDosError( status ) );
380 atom = 0;
381 }
382 }
383 return atom;
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000384}
385
386
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000387/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000388 * GlobalGetAtomNameA (KERNEL32.@)
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000389 *
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000390 * Get a copy of the string associated with an atom.
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000391 *
392 * RETURNS
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000393 * Success: The length of the returned string in characters.
394 * Failure: 0.
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000395 */
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000396UINT WINAPI GlobalGetAtomNameA(
397 ATOM atom, /* [in] Atom identifier */
398 LPSTR buffer, /* [out] Pointer to buffer for atom string */
399 INT count ) /* [in] Size of buffer */
400{
Eric Pouech70342db2006-01-03 17:35:01 +0100401 WCHAR tmpW[MAX_ATOM_LEN + 1];
402 UINT wlen, len = 0, c;
403
404 if (count <= 0) SetLastError( ERROR_MORE_DATA );
405 else if ((wlen = GlobalGetAtomNameW( atom, tmpW, MAX_ATOM_LEN + 1 )))
406 {
407 char tmp[MAX_ATOM_LEN + 1];
408
409 len = WideCharToMultiByte( CP_ACP, 0, tmpW, wlen, tmp, MAX_ATOM_LEN + 1, NULL, NULL );
410 c = min(len, count - 1);
411 memcpy(buffer, tmp, c);
412 buffer[c] = '\0';
413 if (len >= count)
414 {
415 len = 0;
416 SetLastError( ERROR_MORE_DATA );
417 }
418 }
419 return len;
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000420}
421
422
423/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000424 * GetAtomNameA (KERNEL32.@)
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000425 *
426 * Get a copy of the string associated with an atom.
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000427 *
428 * RETURNS
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000429 * Success: The length of the returned string in characters.
430 * Failure: 0.
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000431 */
432UINT WINAPI GetAtomNameA(
433 ATOM atom, /* [in] Atom */
434 LPSTR buffer, /* [out] Pointer to string for atom string */
435 INT count) /* [in] Size of buffer */
436{
Eric Pouech70342db2006-01-03 17:35:01 +0100437 WCHAR tmpW[MAX_ATOM_LEN + 1];
438 UINT wlen, len = 0, c;
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000439
Eric Pouech70342db2006-01-03 17:35:01 +0100440 if (count <= 0) SetLastError( ERROR_MORE_DATA );
441 else if ((wlen = GetAtomNameW( atom, tmpW, MAX_ATOM_LEN + 1 )))
Alexandre Julliard9c2370b2000-08-30 00:00:48 +0000442 {
Eric Pouech70342db2006-01-03 17:35:01 +0100443 char tmp[MAX_ATOM_LEN + 1];
444
445 len = WideCharToMultiByte( CP_ACP, 0, tmpW, wlen, tmp, MAX_ATOM_LEN + 1, NULL, NULL );
446 c = min(len, count - 1);
447 memcpy(buffer, tmp, c);
448 buffer[c] = '\0';
449 if (len >= count)
Alexandre Julliardb849d792000-02-13 13:56:13 +0000450 {
Eric Pouech70342db2006-01-03 17:35:01 +0100451 len = c;
452 SetLastError( ERROR_MORE_DATA );
Alexandre Julliardb849d792000-02-13 13:56:13 +0000453 }
Alexandre Julliardb849d792000-02-13 13:56:13 +0000454 }
Alexandre Julliardb849d792000-02-13 13:56:13 +0000455 return len;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000456}
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000457
458
459/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000460 * GlobalGetAtomNameW (KERNEL32.@)
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000461 *
462 * Unicode version of GlobalGetAtomNameA.
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000463 */
464UINT WINAPI GlobalGetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
465{
Eric Pouech70342db2006-01-03 17:35:01 +0100466 char ptr[sizeof(ATOM_BASIC_INFORMATION) + MAX_ATOM_LEN * sizeof(WCHAR)];
467 ATOM_BASIC_INFORMATION* abi = (ATOM_BASIC_INFORMATION*)ptr;
468 ULONG ptr_size = sizeof(ATOM_BASIC_INFORMATION) + MAX_ATOM_LEN * sizeof(WCHAR);
469 NTSTATUS status;
470 UINT length = 0;
471
472 if (count <= 0)
473 {
474 SetLastError( ERROR_MORE_DATA );
475 return 0;
476 }
477 status = NtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
478 if (status) SetLastError( RtlNtStatusToDosError( status ) );
479 else
480 {
481 length = min( abi->NameLength / sizeof(WCHAR), count);
482 memcpy( buffer, abi->Name, length * sizeof(WCHAR) );
Eric Pouechdccd41a2006-02-06 11:26:57 +0100483 /* yes, the string will not be null terminated if the passed buffer
484 * is one WCHAR too small (and it's not an error)
485 */
Eric Pouech70342db2006-01-03 17:35:01 +0100486 if (length < abi->NameLength / sizeof(WCHAR))
487 {
488 SetLastError( ERROR_MORE_DATA );
489 length = count;
490 }
Eric Pouechdccd41a2006-02-06 11:26:57 +0100491 else if (length < count) buffer[length] = '\0';
Eric Pouech70342db2006-01-03 17:35:01 +0100492 }
493 return length;
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000494}
495
496
497/***********************************************************************
Patrik Stridvalldae8de62001-06-13 20:13:18 +0000498 * GetAtomNameW (KERNEL32.@)
Jon Griffiths4c1fa162003-10-01 03:20:21 +0000499 *
500 * Unicode version of GetAtomNameA.
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000501 */
502UINT WINAPI GetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
503{
Eric Pouech70342db2006-01-03 17:35:01 +0100504 NTSTATUS status;
505 RTL_ATOM_TABLE table;
506 DWORD length;
507 WCHAR tmp[MAX_ATOM_LEN + 1];
508
509 if (count <= 0)
510 {
511 SetLastError( ERROR_MORE_DATA );
512 return 0;
513 }
514 if (!(table = get_local_table( 0 ))) return 0;
515 length = sizeof(tmp);
516 status = RtlQueryAtomInAtomTable( table, atom, NULL, NULL, tmp, &length );
517 if (status)
518 {
519 SetLastError( RtlNtStatusToDosError( status ) );
520 return 0;
521 }
522 length = min(length, (count - 1) * sizeof(WCHAR));
523 if (length) memcpy(buffer, tmp, length);
524 else SetLastError( ERROR_INSUFFICIENT_BUFFER );
525 length /= sizeof(WCHAR);
526 buffer[length] = '\0';
527 return length;
Turchanov Sergei43a27e32000-05-30 20:32:06 +0000528}