blob: aab4592f036df32eaf701e70e571633c4af0ad3b [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 Julliard5f721f81994-01-04 20:14:34 +00005 */
6
7/*
Alexandre Julliard808cb041995-08-17 17:11:36 +00008 * Warning: The code assumes that LocalAlloc() returns a block aligned
9 * on a 4-bytes boundary (because of the shifting done in
10 * HANDLETOATOM). If this is not the case, the allocation code will
11 * have to be changed.
Alexandre Julliard5f721f81994-01-04 20:14:34 +000012 */
13
14#include <stdlib.h>
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000015#include <stdio.h>
Alexandre Julliard5f721f81994-01-04 20:14:34 +000016#include <string.h>
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000017#include <ctype.h>
Alexandre Julliard5f721f81994-01-04 20:14:34 +000018
Patrik Stridvallfdcfdb91999-06-12 14:55:11 +000019#include "wine/winbase16.h"
20#include "wine/winuser16.h"
Marcus Meissner317af321999-02-17 13:51:06 +000021#include "winuser.h"
Patrik Stridvall1ed4ecf1999-06-26 14:58:24 +000022#include "global.h"
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000023#include "instance.h"
24#include "ldt.h"
25#include "stackframe.h"
26#include "user.h"
Alexandre Julliard15657091999-05-23 10:25:25 +000027#include "debugtools.h"
Alexandre Julliard5f721f81994-01-04 20:14:34 +000028
Alexandre Julliardb7258be1995-09-01 15:57:28 +000029#ifdef CONFIG_IPC
30#include "dde_atom.h"
Alexandre Julliardb7258be1995-09-01 15:57:28 +000031#endif
32
Patrik Stridvallb4b9fae1999-04-19 14:56:29 +000033DEFAULT_DEBUG_CHANNEL(atom)
34
Alexandre Julliard5f721f81994-01-04 20:14:34 +000035#define DEFAULT_ATOMTABLE_SIZE 37
36#define MIN_STR_ATOM 0xc000
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000037#define MAX_ATOM_LEN 255
Alexandre Julliard5f721f81994-01-04 20:14:34 +000038
Alexandre Julliard8bbf8181996-09-13 16:50:47 +000039#define ATOMTOHANDLE(atom) ((HANDLE16)(atom) << 2)
Alexandre Julliard5f721f81994-01-04 20:14:34 +000040#define HANDLETOATOM(handle) ((ATOM)(0xc000 | ((handle) >> 2)))
41
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000042#define HAS_ATOM_TABLE(sel) \
43 ((INSTANCEDATA*)PTR_SEG_OFF_TO_LIN(sel,0))->atomtable != 0)
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000044
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000045#define GET_ATOM_TABLE(sel) ((ATOMTABLE*)PTR_SEG_OFF_TO_LIN(sel, \
46 ((INSTANCEDATA*)PTR_SEG_OFF_TO_LIN(sel,0))->atomtable))
Alexandre Julliard737fa071998-11-15 17:29:15 +000047
48typedef struct
49{
50 HANDLE16 next;
51 WORD refCount;
52 BYTE length;
53 BYTE str[1];
54} ATOMENTRY;
55
56typedef struct
57{
58 WORD size;
59 HANDLE16 entries[1];
60} ATOMTABLE;
Alexandre Julliardded30381995-07-06 17:18:27 +000061
Ulrich Weigand9e290211998-11-01 18:00:09 +000062static WORD ATOM_GlobalTable = 0;
Alexandre Julliard5f721f81994-01-04 20:14:34 +000063
64/***********************************************************************
65 * ATOM_InitTable
Alexandre Julliard54c27111998-03-29 19:44:57 +000066 *
67 * NOTES
68 * Should this validate the value of entries to be 0 < x < 0x3fff?
69 *
70 * RETURNS
71 * Handle: Success
72 * 0: Failure
Alexandre Julliard5f721f81994-01-04 20:14:34 +000073 */
Alexandre Julliard54c27111998-03-29 19:44:57 +000074static HANDLE16 ATOM_InitTable(
75 WORD selector, /* [in] Segment */
76 WORD entries /* [in] Size of atom table */
77) {
Alexandre Julliard5f721f81994-01-04 20:14:34 +000078 int i;
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +000079 HANDLE16 handle;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000080 ATOMTABLE *table;
Alexandre Julliard8d24ae61994-04-05 21:42:43 +000081
Ulrich Weigand9e290211998-11-01 18:00:09 +000082 /* We consider the first table to be initialized as the global table.
83 * This works, as USER (both built-in and native) is the first one to
84 * register ...
85 */
86
87 if (!ATOM_GlobalTable) ATOM_GlobalTable = selector;
88
89
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000090 /* Allocate the table */
91
92 handle = LOCAL_Alloc( selector, LMEM_FIXED,
Alexandre Julliard8bbf8181996-09-13 16:50:47 +000093 sizeof(ATOMTABLE) + (entries-1) * sizeof(HANDLE16) );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +000094 if (!handle) return 0;
95 table = (ATOMTABLE *)PTR_SEG_OFF_TO_LIN( selector, handle );
96 table->size = entries;
97 for (i = 0; i < entries; i++) table->entries[i] = 0;
98
99 /* Store a pointer to the table in the instance data */
100
101 ((INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( selector, 0 ))->atomtable = handle;
102 return handle;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000103}
104
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000105
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000106/***********************************************************************
107 * ATOM_Init
108 *
109 * Global table initialisation.
110 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000111BOOL ATOM_Init( WORD globalTableSel )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000112{
Ulrich Weigand9e290211998-11-01 18:00:09 +0000113 return ATOM_InitTable( globalTableSel, DEFAULT_ATOMTABLE_SIZE ) != 0;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000114}
115
116
117/***********************************************************************
118 * ATOM_GetTable
119 *
120 * Return a pointer to the atom table of a given segment, creating
121 * it if necessary.
Alexandre Julliard54c27111998-03-29 19:44:57 +0000122 *
123 * RETURNS
124 * Pointer to table: Success
125 * NULL: Failure
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000126 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000127static ATOMTABLE *ATOM_GetTable(
128 WORD selector, /* [in] Segment */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000129 BOOL create /* [in] Create */ )
Alexandre Julliard737fa071998-11-15 17:29:15 +0000130{
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000131 INSTANCEDATA *ptr = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( selector, 0 );
Alexandre Julliard737fa071998-11-15 17:29:15 +0000132 if (ptr->atomtable)
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000133 {
Alexandre Julliard737fa071998-11-15 17:29:15 +0000134 ATOMTABLE *table = (ATOMTABLE *)((char *)ptr + ptr->atomtable);
135 if (table->size) return table;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000136 }
Alexandre Julliard737fa071998-11-15 17:29:15 +0000137 if (!create) return NULL;
138 if (!ATOM_InitTable( selector, DEFAULT_ATOMTABLE_SIZE )) return NULL;
139 /* Reload ptr in case it moved in linear memory */
140 ptr = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( selector, 0 );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000141 return (ATOMTABLE *)((char *)ptr + ptr->atomtable);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000142}
143
144
145/***********************************************************************
146 * ATOM_MakePtr
147 *
148 * Make an ATOMENTRY pointer from a handle (obtained from GetAtomHandle()).
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000149 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000150static ATOMENTRY *ATOM_MakePtr(
151 WORD selector, /* [in] Segment */
152 HANDLE16 handle /* [in] Handle */
153) {
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000154 return (ATOMENTRY *)PTR_SEG_OFF_TO_LIN( selector, handle );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000155}
156
157
158/***********************************************************************
159 * ATOM_Hash
Alexandre Julliard54c27111998-03-29 19:44:57 +0000160 * RETURNS
161 * The hash value for the input string
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000162 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000163static WORD ATOM_Hash(
164 WORD entries, /* [in] Total number of entries */
165 LPCSTR str, /* [in] Pointer to string to hash */
166 WORD len /* [in] Length of string */
167) {
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000168 WORD i, hash = 0;
169
Alexandre Julliard15657091999-05-23 10:25:25 +0000170 TRACE("%x, %s, %x\n", entries, str, len);
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000171
Alexandre Julliardcdd09231994-01-12 11:12:51 +0000172 for (i = 0; i < len; i++) hash ^= toupper(str[i]) + i;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000173 return hash % entries;
174}
175
Alexandre Julliarda3960291999-02-26 11:11:13 +0000176static BOOL ATOM_IsIntAtom(LPCSTR atomstr,WORD *atomid) {
Marcus Meissner88065ba1998-12-02 10:00:48 +0000177 LPSTR xend;
178
179 if (!HIWORD(atomstr)) {
180 *atomid = LOWORD(atomstr);
181 return TRUE;
182 }
183 if (atomstr[0]!='#')
184 return FALSE;
185 *atomid=strtol(atomstr+1,&xend,10);
186 if (*xend) {
Alexandre Julliard15657091999-05-23 10:25:25 +0000187 FIXME("found atom named '%s'\n",atomstr);
Marcus Meissner88065ba1998-12-02 10:00:48 +0000188 return FALSE;
189 }
190 return TRUE;
191}
192
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000193
194/***********************************************************************
195 * ATOM_AddAtom
Alexandre Julliard54c27111998-03-29 19:44:57 +0000196 *
Alexandre Julliard642d3131998-07-12 19:29:36 +0000197 * Windows DWORD aligns the atom entry size.
198 * The remaining unused string space created by the alignment
199 * gets padded with '\0's in a certain way to ensure
200 * that at least one trailing '\0' remains.
201 *
Alexandre Julliard54c27111998-03-29 19:44:57 +0000202 * RETURNS
203 * Atom: Success
204 * 0: Failure
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000205 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000206static ATOM ATOM_AddAtom(
207 WORD selector, /* [in] Segment */
208 LPCSTR str /* [in] Pointer to the string to add */
209) {
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000210 WORD hash;
Alexandre Julliard8bbf8181996-09-13 16:50:47 +0000211 HANDLE16 entry;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000212 ATOMENTRY * entryPtr;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000213 ATOMTABLE * table;
Alexandre Julliard642d3131998-07-12 19:29:36 +0000214 int len, ae_len;
Marcus Meissner88065ba1998-12-02 10:00:48 +0000215 WORD iatom;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000216
Alexandre Julliard15657091999-05-23 10:25:25 +0000217 TRACE("0x%x, %s\n", selector, str);
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000218
Marcus Meissner88065ba1998-12-02 10:00:48 +0000219 if (ATOM_IsIntAtom(str,&iatom))
220 return iatom;
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000221 if ((len = strlen( str )) > MAX_ATOM_LEN) len = MAX_ATOM_LEN;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000222 if (!(table = ATOM_GetTable( selector, TRUE ))) return 0;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000223 hash = ATOM_Hash( table->size, str, len );
224 entry = table->entries[hash];
225 while (entry)
226 {
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000227 entryPtr = ATOM_MakePtr( selector, entry );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000228 if ((entryPtr->length == len) &&
Alexandre Julliarda3960291999-02-26 11:11:13 +0000229 (!lstrncmpiA( entryPtr->str, str, len )))
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000230 {
231 entryPtr->refCount++;
Alexandre Julliard15657091999-05-23 10:25:25 +0000232 TRACE("-- existing 0x%x\n", entry);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000233 return HANDLETOATOM( entry );
234 }
235 entry = entryPtr->next;
236 }
Alexandre Julliard8d24ae61994-04-05 21:42:43 +0000237
Alexandre Julliard642d3131998-07-12 19:29:36 +0000238 ae_len = (sizeof(ATOMENTRY)+len+3) & ~3;
239 entry = LOCAL_Alloc( selector, LMEM_FIXED, ae_len);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000240 if (!entry) return 0;
Alexandre Julliard02ed4c21996-03-02 19:34:10 +0000241 /* Reload the table ptr in case it moved in linear memory */
242 table = ATOM_GetTable( selector, FALSE );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000243 entryPtr = ATOM_MakePtr( selector, entry );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000244 entryPtr->next = table->entries[hash];
245 entryPtr->refCount = 1;
246 entryPtr->length = len;
Alexandre Julliard642d3131998-07-12 19:29:36 +0000247 strncpy( entryPtr->str, str, ae_len - sizeof(ATOMENTRY) + 1); /* always use strncpy ('\0's padding) */
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000248 table->entries[hash] = entry;
Alexandre Julliard15657091999-05-23 10:25:25 +0000249 TRACE("-- new 0x%x\n", entry);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000250 return HANDLETOATOM( entry );
251}
252
253
254/***********************************************************************
255 * ATOM_DeleteAtom
Alexandre Julliard54c27111998-03-29 19:44:57 +0000256 * RETURNS
257 * 0: Success
258 * Atom: Failure
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000259 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000260static ATOM ATOM_DeleteAtom(
261 WORD selector, /* [in] Segment */
262 ATOM atom /* [in] Atom to delete */
263) {
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000264 ATOMENTRY * entryPtr;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000265 ATOMTABLE * table;
Alexandre Julliard8bbf8181996-09-13 16:50:47 +0000266 HANDLE16 entry, *prevEntry;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000267 WORD hash;
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000268
Alexandre Julliard15657091999-05-23 10:25:25 +0000269 TRACE("0x%x, 0x%x\n", selector, atom);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000270
271 if (atom < MIN_STR_ATOM) return 0; /* Integer atom */
272
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000273 if (!(table = ATOM_GetTable( selector, FALSE ))) return 0;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000274 entry = ATOMTOHANDLE( atom );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000275 entryPtr = ATOM_MakePtr( selector, entry );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000276
277 /* Find previous atom */
278 hash = ATOM_Hash( table->size, entryPtr->str, entryPtr->length );
279 prevEntry = &table->entries[hash];
280 while (*prevEntry && *prevEntry != entry)
281 {
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000282 ATOMENTRY * prevEntryPtr = ATOM_MakePtr( selector, *prevEntry );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000283 prevEntry = &prevEntryPtr->next;
284 }
285 if (!*prevEntry) return atom;
286
287 /* Delete atom */
288 if (--entryPtr->refCount == 0)
289 {
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000290 *prevEntry = entryPtr->next;
291 LOCAL_Free( selector, entry );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000292 }
293 return 0;
294}
295
296
297/***********************************************************************
298 * ATOM_FindAtom
Alexandre Julliard54c27111998-03-29 19:44:57 +0000299 * RETURNS
300 * Atom: Success
301 * 0: Failure
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000302 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000303static ATOM ATOM_FindAtom(
304 WORD selector, /* [in] Segment */
305 LPCSTR str /* [in] Pointer to string to find */
306) {
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000307 ATOMTABLE * table;
Marcus Meissner88065ba1998-12-02 10:00:48 +0000308 WORD hash,iatom;
Alexandre Julliard8bbf8181996-09-13 16:50:47 +0000309 HANDLE16 entry;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000310 int len;
Alexandre Julliard808cb041995-08-17 17:11:36 +0000311
Alexandre Julliard15657091999-05-23 10:25:25 +0000312 TRACE("%x, %s\n", selector, str);
Marcus Meissner88065ba1998-12-02 10:00:48 +0000313 if (ATOM_IsIntAtom(str,&iatom))
314 return iatom;
Alexandre Julliard808cb041995-08-17 17:11:36 +0000315 if ((len = strlen( str )) > 255) len = 255;
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000316 if (!(table = ATOM_GetTable( selector, FALSE ))) return 0;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000317 hash = ATOM_Hash( table->size, str, len );
318 entry = table->entries[hash];
319 while (entry)
320 {
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000321 ATOMENTRY * entryPtr = ATOM_MakePtr( selector, entry );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000322 if ((entryPtr->length == len) &&
Alexandre Julliarda3960291999-02-26 11:11:13 +0000323 (!lstrncmpiA( entryPtr->str, str, len )))
Alexandre Julliard15657091999-05-23 10:25:25 +0000324 { TRACE("-- found %x\n", entry);
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000325 return HANDLETOATOM( entry );
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000326 }
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000327 entry = entryPtr->next;
328 }
Alexandre Julliard15657091999-05-23 10:25:25 +0000329 TRACE("-- not found\n");
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000330 return 0;
331}
332
333
334/***********************************************************************
335 * ATOM_GetAtomName
Alexandre Julliard54c27111998-03-29 19:44:57 +0000336 * RETURNS
337 * Length of string copied to buffer: Success
338 * 0: Failure
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000339 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000340static UINT ATOM_GetAtomName(
Alexandre Julliard54c27111998-03-29 19:44:57 +0000341 WORD selector, /* [in] Segment */
342 ATOM atom, /* [in] Atom identifier */
343 LPSTR buffer, /* [out] Pointer to buffer for atom string */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000344 INT count /* [in] Size of buffer */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000345) {
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000346 ATOMTABLE * table;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000347 ATOMENTRY * entryPtr;
Alexandre Julliard8bbf8181996-09-13 16:50:47 +0000348 HANDLE16 entry;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000349 char * strPtr;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000350 UINT len;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000351 char text[8];
352
Alexandre Julliard15657091999-05-23 10:25:25 +0000353 TRACE("%x, %x\n", selector, atom);
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000354
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000355 if (!count) return 0;
356 if (atom < MIN_STR_ATOM)
357 {
358 sprintf( text, "#%d", atom );
359 len = strlen(text);
360 strPtr = text;
361 }
362 else
363 {
Alexandre Julliard767e6f61998-08-09 12:47:43 +0000364 if (!(table = ATOM_GetTable( selector, FALSE ))) return 0;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000365 entry = ATOMTOHANDLE( atom );
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000366 entryPtr = ATOM_MakePtr( selector, entry );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000367 len = entryPtr->length;
368 strPtr = entryPtr->str;
369 }
370 if (len >= count) len = count-1;
371 memcpy( buffer, strPtr, len );
372 buffer[len] = '\0';
373 return len;
374}
375
376
377/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000378 * InitAtomTable16 (KERNEL.68)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000379 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000380WORD WINAPI InitAtomTable16( WORD entries )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000381{
Alexandre Julliard737fa071998-11-15 17:29:15 +0000382 if (!entries) entries = DEFAULT_ATOMTABLE_SIZE; /* sanity check */
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000383 return ATOM_InitTable( CURRENT_DS, entries );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000384}
385
386
387/***********************************************************************
388 * GetAtomHandle (KERNEL.73)
389 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000390HANDLE16 WINAPI GetAtomHandle16( ATOM atom )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000391{
392 if (atom < MIN_STR_ATOM) return 0;
393 return ATOMTOHANDLE( atom );
394}
395
396
397/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000398 * AddAtom16 (KERNEL.70)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000399 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000400ATOM WINAPI AddAtom16( SEGPTR str )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000401{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000402 ATOM atom;
403 HANDLE16 ds = CURRENT_DS;
404
405 if (!HIWORD(str)) return (ATOM)LOWORD(str); /* Integer atom */
406 if (SELECTOR_TO_ENTRY(LOWORD(str)) == SELECTOR_TO_ENTRY(ds))
407 {
408 /* If the string is in the same data segment as the atom table, make */
409 /* a copy of the string to be sure it doesn't move in linear memory. */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000410 char buffer[MAX_ATOM_LEN+1];
Alexandre Julliarda3960291999-02-26 11:11:13 +0000411 lstrcpynA( buffer, (char *)PTR_SEG_TO_LIN(str), sizeof(buffer) );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000412 atom = ATOM_AddAtom( ds, buffer );
413 }
414 else atom = ATOM_AddAtom( ds, (LPCSTR)PTR_SEG_TO_LIN(str) );
415 return atom;
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000416}
417
418
419/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000420 * AddAtom32A (KERNEL32.0)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000421 * Adds a string to the atom table and returns the atom identifying the
422 * string.
423 *
424 * RETURNS
425 * Atom: Success
426 * 0: Failure
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000427 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000428ATOM WINAPI AddAtomA(
Alexandre Julliard54c27111998-03-29 19:44:57 +0000429 LPCSTR str /* [in] Pointer to string to add */
430) {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000431 return GlobalAddAtomA( str ); /* FIXME */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000432}
433
434
435/***********************************************************************
436 * AddAtom32W (KERNEL32.1)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000437 * See AddAtom32A
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000438 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000439ATOM WINAPI AddAtomW( LPCWSTR str )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000440{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000441 return GlobalAddAtomW( str ); /* FIXME */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000442}
443
444
445/***********************************************************************
446 * DeleteAtom16 (KERNEL.71)
447 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000448ATOM WINAPI DeleteAtom16( ATOM atom )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000449{
Alexandre Julliarde2abbb11995-03-19 17:39:39 +0000450 return ATOM_DeleteAtom( CURRENT_DS, atom );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000451}
452
453
454/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000455 * DeleteAtom32 (KERNEL32.69)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000456 * Decrements the reference count of a string atom. If count becomes
457 * zero, the string associated with the atom is removed from the table.
458 *
459 * RETURNS
460 * 0: Success
461 * Atom: Failure
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000462 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000463ATOM WINAPI DeleteAtom(
Alexandre Julliard54c27111998-03-29 19:44:57 +0000464 ATOM atom /* [in] Atom to delete */
465) {
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000466 return GlobalDeleteAtom( atom ); /* FIXME */
467}
468
469
470/***********************************************************************
471 * FindAtom16 (KERNEL.69)
472 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000473ATOM WINAPI FindAtom16( SEGPTR str )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000474{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000475 if (!HIWORD(str)) return (ATOM)LOWORD(str); /* Integer atom */
476 return ATOM_FindAtom( CURRENT_DS, (LPCSTR)PTR_SEG_TO_LIN(str) );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000477}
478
479
480/***********************************************************************
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000481 * FindAtom32A (KERNEL32.117)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000482 * Searches the local atom table for the string and returns the atom
483 * associated with that string.
484 *
485 * RETURNS
486 * Atom: Success
487 * 0: Failure
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000488 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000489ATOM WINAPI FindAtomA(
Alexandre Julliard54c27111998-03-29 19:44:57 +0000490 LPCSTR str /* [in] Pointer to string to find */
491) {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000492 return GlobalFindAtomA( str ); /* FIXME */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000493}
494
495
496/***********************************************************************
497 * FindAtom32W (KERNEL32.118)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000498 * See FindAtom32A
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000499 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000500ATOM WINAPI FindAtomW( LPCWSTR str )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000501{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000502 return GlobalFindAtomW( str ); /* FIXME */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000503}
504
505
506/***********************************************************************
507 * GetAtomName16 (KERNEL.72)
508 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000509UINT16 WINAPI GetAtomName16( ATOM atom, LPSTR buffer, INT16 count )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000510{
511 return (UINT16)ATOM_GetAtomName( CURRENT_DS, atom, buffer, count );
512}
513
514
515/***********************************************************************
516 * GetAtomName32A (KERNEL32.149)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000517 * Retrieves a copy of the string associated with the atom.
518 *
519 * RETURNS
520 * Length of string: Success
521 * 0: Failure
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000522 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000523UINT WINAPI GetAtomNameA(
Alexandre Julliard54c27111998-03-29 19:44:57 +0000524 ATOM atom, /* [in] Atom */
525 LPSTR buffer, /* [out] Pointer to string for atom string */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000526 INT count /* [in] Size of buffer */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000527) {
Alexandre Julliarda3960291999-02-26 11:11:13 +0000528 return GlobalGetAtomNameA( atom, buffer, count ); /* FIXME */
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000529}
530
531
532/***********************************************************************
533 * GetAtomName32W (KERNEL32.150)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000534 * See GetAtomName32A
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000535 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000536UINT WINAPI GetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
Alexandre Julliardf0cbfa01997-02-15 14:29:56 +0000537{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000538 return GlobalGetAtomNameW( atom, buffer, count ); /* FIXME */
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000539}
540
541
542/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000543 * GlobalAddAtom16 (USER.268)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000544 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000545ATOM WINAPI GlobalAddAtom16( SEGPTR str )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000546{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000547 if (!HIWORD(str)) return (ATOM)LOWORD(str); /* Integer atom */
Alexandre Julliardb7258be1995-09-01 15:57:28 +0000548#ifdef CONFIG_IPC
Alexandre Julliard0623a6f1998-01-18 18:01:49 +0000549 return DDE_GlobalAddAtom( str );
550#else
Ulrich Weigand9e290211998-11-01 18:00:09 +0000551 return ATOM_AddAtom( ATOM_GlobalTable, (LPCSTR)PTR_SEG_TO_LIN(str) );
Alexandre Julliard0623a6f1998-01-18 18:01:49 +0000552#endif
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000553}
554
555
556/***********************************************************************
557 * GlobalAddAtom32A (KERNEL32.313)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000558 * Adds a character string to the global atom table and returns a unique
559 * value identifying the string.
560 *
561 * RETURNS
562 * Atom: Success
563 * 0: Failure
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000564 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000565ATOM WINAPI GlobalAddAtomA(
Alexandre Julliard54c27111998-03-29 19:44:57 +0000566 LPCSTR str /* [in] Pointer to string to add */
567) {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000568 if (!HIWORD(str)) return (ATOM)LOWORD(str); /* Integer atom */
Ulrich Weigand9e290211998-11-01 18:00:09 +0000569 return ATOM_AddAtom( ATOM_GlobalTable, str );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000570}
571
572
573/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000574 * GlobalAddAtom32W (KERNEL32.314)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000575 * See GlobalAddAtom32A
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000576 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000577ATOM WINAPI GlobalAddAtomW( LPCWSTR str )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000578{
579 char buffer[MAX_ATOM_LEN+1];
580 if (!HIWORD(str)) return (ATOM)LOWORD(str); /* Integer atom */
Alexandre Julliardca22b331996-07-12 19:02:39 +0000581 lstrcpynWtoA( buffer, str, sizeof(buffer) );
Ulrich Weigand9e290211998-11-01 18:00:09 +0000582 return ATOM_AddAtom( ATOM_GlobalTable, buffer );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000583}
584
585
586/***********************************************************************
587 * GlobalDeleteAtom (USER.269) (KERNEL32.317)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000588 * Decrements the reference count of a string atom. If the count is
589 * zero, the string associated with the atom is removed from the table.
590 *
591 * RETURNS
592 * 0: Success
593 * Atom: Failure
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000594 */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000595ATOM WINAPI GlobalDeleteAtom(
596 ATOM atom /* [in] Atom to delete */
597) {
Alexandre Julliardb7258be1995-09-01 15:57:28 +0000598#ifdef CONFIG_IPC
Alexandre Julliard0623a6f1998-01-18 18:01:49 +0000599 return DDE_GlobalDeleteAtom( atom );
600#else
Ulrich Weigand9e290211998-11-01 18:00:09 +0000601 return ATOM_DeleteAtom( ATOM_GlobalTable, atom );
Alexandre Julliard0623a6f1998-01-18 18:01:49 +0000602#endif
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000603}
604
605
606/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000607 * GlobalFindAtom16 (USER.270)
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000608 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000609ATOM WINAPI GlobalFindAtom16( SEGPTR str )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000610{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000611 if (!HIWORD(str)) return (ATOM)LOWORD(str); /* Integer atom */
Alexandre Julliardb7258be1995-09-01 15:57:28 +0000612#ifdef CONFIG_IPC
Alexandre Julliard0623a6f1998-01-18 18:01:49 +0000613 return DDE_GlobalFindAtom( str );
614#else
Ulrich Weigand9e290211998-11-01 18:00:09 +0000615 return ATOM_FindAtom( ATOM_GlobalTable, (LPCSTR)PTR_SEG_TO_LIN(str) );
Alexandre Julliard0623a6f1998-01-18 18:01:49 +0000616#endif
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000617}
618
619
620/***********************************************************************
621 * GlobalFindAtom32A (KERNEL32.318)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000622 * Searches the atom table for the string and returns the atom
623 * associated with it.
624 *
625 * RETURNS
626 * Atom: Success
627 * 0: Failure
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000628 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000629ATOM WINAPI GlobalFindAtomA(
Alexandre Julliard54c27111998-03-29 19:44:57 +0000630 LPCSTR str /* [in] Pointer to string to search for */
631) {
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000632 if (!HIWORD(str)) return (ATOM)LOWORD(str); /* Integer atom */
Ulrich Weigand9e290211998-11-01 18:00:09 +0000633 return ATOM_FindAtom( ATOM_GlobalTable, str );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000634}
635
636
637/***********************************************************************
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000638 * GlobalFindAtom32W (KERNEL32.319)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000639 * See GlobalFindAtom32A
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000640 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000641ATOM WINAPI GlobalFindAtomW( LPCWSTR str )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000642{
643 char buffer[MAX_ATOM_LEN+1];
644 if (!HIWORD(str)) return (ATOM)LOWORD(str); /* Integer atom */
Alexandre Julliardca22b331996-07-12 19:02:39 +0000645 lstrcpynWtoA( buffer, str, sizeof(buffer) );
Ulrich Weigand9e290211998-11-01 18:00:09 +0000646 return ATOM_FindAtom( ATOM_GlobalTable, buffer );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000647}
648
649
650/***********************************************************************
651 * GlobalGetAtomName16 (USER.271)
652 */
Alexandre Julliard670cdc41997-08-24 16:00:30 +0000653UINT16 WINAPI GlobalGetAtomName16( ATOM atom, LPSTR buffer, INT16 count )
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000654{
Alexandre Julliardb7258be1995-09-01 15:57:28 +0000655#ifdef CONFIG_IPC
Alexandre Julliard0623a6f1998-01-18 18:01:49 +0000656 return DDE_GlobalGetAtomName( atom, buffer, count );
657#else
Ulrich Weigand9e290211998-11-01 18:00:09 +0000658 return (UINT16)ATOM_GetAtomName( ATOM_GlobalTable, atom, buffer, count );
Alexandre Julliard0623a6f1998-01-18 18:01:49 +0000659#endif
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000660}
661
662
663/***********************************************************************
664 * GlobalGetAtomName32A (KERNEL32.323)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000665 * Retrieves a copy of the string associated with an atom.
666 *
667 * RETURNS
668 * Length of string in characters: Success
669 * 0: Failure
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000670 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000671UINT WINAPI GlobalGetAtomNameA(
Alexandre Julliard54c27111998-03-29 19:44:57 +0000672 ATOM atom, /* [in] Atom identifier */
673 LPSTR buffer, /* [out] Pointer to buffer for atom string */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000674 INT count /* [in] Size of buffer */
Alexandre Julliard54c27111998-03-29 19:44:57 +0000675) {
Ulrich Weigand9e290211998-11-01 18:00:09 +0000676 return ATOM_GetAtomName( ATOM_GlobalTable, atom, buffer, count );
Alexandre Julliard5f721f81994-01-04 20:14:34 +0000677}
Alexandre Julliard2ace16a1996-04-28 15:09:19 +0000678
Alexandre Julliard54c27111998-03-29 19:44:57 +0000679
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000680/***********************************************************************
681 * GlobalGetAtomName32W (KERNEL32.324)
Alexandre Julliard54c27111998-03-29 19:44:57 +0000682 * See GlobalGetAtomName32A
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000683 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000684UINT WINAPI GlobalGetAtomNameW( ATOM atom, LPWSTR buffer, INT count )
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000685{
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000686 char tmp[MAX_ATOM_LEN+1];
Ulrich Weigand9e290211998-11-01 18:00:09 +0000687 ATOM_GetAtomName( ATOM_GlobalTable, atom, tmp, sizeof(tmp) );
Alexandre Julliardca22b331996-07-12 19:02:39 +0000688 lstrcpynAtoW( buffer, tmp, count );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000689 return lstrlenW( buffer );
Alexandre Julliarde2bfa4c1996-05-16 18:21:06 +0000690}