2003-07-10 Casper S. Hornstrup <chorns@users.sourceforge.net>
[reactos.git] / reactos / lib / kernel32 / misc / atom.c
1 /* $Id: atom.c,v 1.17 2003/07/10 18:50:51 chorns Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/misc/atom.c
6 * PURPOSE: Atom functions
7 * PROGRAMMER: Eric Kohl ( ariadne@xs4all.nl)
8 * UPDATE HISTORY:
9 * Created 01/11/98
10 * Full rewrite 27/05/2001
11 */
12
13 #include <k32.h>
14
15 #define NDEBUG
16 #include <kernel32/kernel32.h>
17
18
19 /* GLOBALS *******************************************************************/
20
21 static PRTL_ATOM_TABLE LocalAtomTable = NULL;
22
23 static PRTL_ATOM_TABLE GetLocalAtomTable(VOID);
24
25
26 /* FUNCTIONS *****************************************************************/
27
28 /*
29 * @implemented
30 */
31 ATOM STDCALL
32 GlobalAddAtomA(LPCSTR lpString)
33 {
34 UNICODE_STRING AtomName;
35 NTSTATUS Status;
36 ATOM Atom;
37
38 if (HIWORD((ULONG)lpString) == 0)
39 {
40 if ((ULONG)lpString >= 0xC000)
41 {
42 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
43 return (ATOM)0;
44 }
45 return (ATOM)LOWORD((ULONG)lpString);
46 }
47
48 RtlCreateUnicodeStringFromAsciiz(&AtomName,
49 (LPSTR)lpString);
50
51 Status = NtAddAtom(AtomName.Buffer,
52 &Atom);
53 RtlFreeUnicodeString(&AtomName);
54 if (!NT_SUCCESS(Status))
55 {
56 SetLastErrorByStatus(Status);
57 return (ATOM)0;
58 }
59
60 return Atom;
61 }
62
63
64 /*
65 * @implemented
66 */
67 ATOM STDCALL
68 GlobalAddAtomW(LPCWSTR lpString)
69 {
70 ATOM Atom;
71 NTSTATUS Status;
72
73 if (HIWORD((ULONG)lpString) == 0)
74 {
75 if ((ULONG)lpString >= 0xC000)
76 {
77 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
78 return (ATOM)0;
79 }
80 return (ATOM)LOWORD((ULONG)lpString);
81 }
82
83 Status = NtAddAtom((LPWSTR)lpString,
84 &Atom);
85 if (!NT_SUCCESS(Status))
86 {
87 SetLastErrorByStatus(Status);
88 return (ATOM)0;
89 }
90
91 return Atom;
92 }
93
94
95 /*
96 * @implemented
97 */
98 ATOM STDCALL
99 GlobalDeleteAtom(ATOM nAtom)
100 {
101 NTSTATUS Status;
102
103 if (nAtom < 0xC000)
104 {
105 return 0;
106 }
107
108 Status = NtDeleteAtom(nAtom);
109 if (!NT_SUCCESS(Status))
110 {
111 SetLastErrorByStatus(Status);
112 return nAtom;
113 }
114
115 return 0;
116 }
117
118
119 /*
120 * @implemented
121 */
122 ATOM STDCALL
123 GlobalFindAtomA(LPCSTR lpString)
124 {
125 UNICODE_STRING AtomName;
126 NTSTATUS Status;
127 ATOM Atom;
128
129 if (HIWORD((ULONG)lpString) == 0)
130 {
131 if ((ULONG)lpString >= 0xC000)
132 {
133 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
134 return (ATOM)0;
135 }
136 return (ATOM)LOWORD((ULONG)lpString);
137 }
138
139 RtlCreateUnicodeStringFromAsciiz(&AtomName,
140 (LPSTR)lpString);
141 Status = NtFindAtom(AtomName.Buffer,
142 &Atom);
143 RtlFreeUnicodeString(&AtomName);
144 if (!NT_SUCCESS(Status))
145 {
146 SetLastErrorByStatus(Status);
147 return (ATOM)0;
148 }
149
150 return Atom;
151 }
152
153
154 /*
155 * @implemented
156 */
157 ATOM STDCALL
158 GlobalFindAtomW(LPCWSTR lpString)
159 {
160 ATOM Atom;
161 NTSTATUS Status;
162
163 if (HIWORD((ULONG)lpString) == 0)
164 {
165 if ((ULONG)lpString >= 0xC000)
166 {
167 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
168 return (ATOM)0;
169 }
170 return (ATOM)LOWORD((ULONG)lpString);
171 }
172
173 Status = NtFindAtom((LPWSTR)lpString,
174 &Atom);
175 if (!NT_SUCCESS(Status))
176 {
177 SetLastErrorByStatus(Status);
178 return (ATOM)0;
179 }
180
181 return Atom;
182 }
183
184
185 UINT STDCALL
186 GlobalGetAtomNameA(ATOM nAtom,
187 LPSTR lpBuffer,
188 int nSize)
189 {
190 PATOM_BASIC_INFORMATION Buffer;
191 UNICODE_STRING AtomNameU;
192 ANSI_STRING AtomName;
193 ULONG BufferSize;
194 ULONG ReturnLength;
195 NTSTATUS Status;
196
197 BufferSize = sizeof(ATOM_BASIC_INFORMATION) + nSize * sizeof(WCHAR);
198 Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
199 HEAP_ZERO_MEMORY,
200 BufferSize);
201
202 Status = NtQueryInformationAtom(nAtom,
203 AtomBasicInformation,
204 (PVOID)&Buffer,
205 BufferSize,
206 &ReturnLength);
207 if (!NT_SUCCESS(Status))
208 {
209 RtlFreeHeap(RtlGetProcessHeap(),
210 0,
211 Buffer);
212 return 0;
213 }
214
215 RtlInitUnicodeString(&AtomNameU,
216 Buffer->Name);
217 AtomName.Buffer = lpBuffer;
218 AtomName.Length = 0;
219 AtomName.MaximumLength = nSize;
220 RtlUnicodeStringToAnsiString(&AtomName,
221 &AtomNameU,
222 FALSE);
223
224 ReturnLength = AtomName.Length;
225 RtlFreeHeap(RtlGetProcessHeap(),
226 0,
227 Buffer);
228
229 return ReturnLength;
230 }
231
232
233 /*
234 * @implemented
235 */
236 UINT STDCALL
237 GlobalGetAtomNameW(ATOM nAtom,
238 LPWSTR lpBuffer,
239 int nSize)
240 {
241 PATOM_BASIC_INFORMATION Buffer;
242 ULONG BufferSize;
243 ULONG ReturnLength;
244 NTSTATUS Status;
245
246 BufferSize = sizeof(ATOM_BASIC_INFORMATION) + nSize * sizeof(WCHAR);
247 Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
248 HEAP_ZERO_MEMORY,
249 BufferSize);
250
251 Status = NtQueryInformationAtom(nAtom,
252 AtomBasicInformation,
253 (PVOID)&Buffer,
254 BufferSize,
255 &ReturnLength);
256 if (!NT_SUCCESS(Status))
257 {
258 RtlFreeHeap(RtlGetProcessHeap(),
259 0,
260 Buffer);
261 return 0;
262 }
263
264 wcscpy(lpBuffer, Buffer->Name);
265 ReturnLength = Buffer->NameLength / sizeof(WCHAR);
266 RtlFreeHeap(RtlGetProcessHeap(),
267 0,
268 Buffer);
269
270 return ReturnLength;
271 }
272
273
274 static PRTL_ATOM_TABLE
275 GetLocalAtomTable(VOID)
276 {
277 if (LocalAtomTable != NULL)
278 {
279 return LocalAtomTable;
280 }
281 RtlCreateAtomTable(37,
282 &LocalAtomTable);
283 return LocalAtomTable;
284 }
285
286
287 /*
288 * @implemented
289 */
290 BOOL STDCALL
291 InitAtomTable(DWORD nSize)
292 {
293 NTSTATUS Status;
294
295 /* nSize should be a prime number */
296
297 if ( nSize < 4 || nSize >= 512 )
298 {
299 nSize = 37;
300 }
301
302 if (LocalAtomTable == NULL)
303 {
304 Status = RtlCreateAtomTable(nSize,
305 &LocalAtomTable);
306 if (!NT_SUCCESS(Status))
307 {
308 SetLastErrorByStatus(Status);
309 return FALSE;
310 }
311 }
312
313 return TRUE;
314 }
315
316
317 /*
318 * @implemented
319 */
320 ATOM STDCALL
321 AddAtomA(LPCSTR lpString)
322 {
323 PRTL_ATOM_TABLE AtomTable;
324 UNICODE_STRING AtomName;
325 NTSTATUS Status;
326 ATOM Atom;
327
328 if (HIWORD((ULONG)lpString) == 0)
329 {
330 if ((ULONG)lpString >= 0xC000)
331 {
332 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
333 return (ATOM)0;
334 }
335 return (ATOM)LOWORD((ULONG)lpString);
336 }
337
338 AtomTable = GetLocalAtomTable();
339
340 RtlCreateUnicodeStringFromAsciiz(&AtomName,
341 (LPSTR)lpString);
342
343 Status = RtlAddAtomToAtomTable(AtomTable,
344 AtomName.Buffer,
345 &Atom);
346 RtlFreeUnicodeString(&AtomName);
347 if (!NT_SUCCESS(Status))
348 {
349 SetLastErrorByStatus(Status);
350 return (ATOM)0;
351 }
352
353 return Atom;
354 }
355
356
357 /*
358 * @implemented
359 */
360 ATOM STDCALL
361 AddAtomW(LPCWSTR lpString)
362 {
363 PRTL_ATOM_TABLE AtomTable;
364 ATOM Atom;
365 NTSTATUS Status;
366
367 if (HIWORD((ULONG)lpString) == 0)
368 {
369 if ((ULONG)lpString >= 0xC000)
370 {
371 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
372 return (ATOM)0;
373 }
374 return (ATOM)LOWORD((ULONG)lpString);
375 }
376
377 AtomTable = GetLocalAtomTable();
378
379 Status = RtlAddAtomToAtomTable(AtomTable,
380 (LPWSTR)lpString,
381 &Atom);
382 if (!NT_SUCCESS(Status))
383 {
384 SetLastErrorByStatus(Status);
385 return (ATOM)0;
386 }
387
388 return Atom;
389 }
390
391
392 /*
393 * @implemented
394 */
395 ATOM STDCALL
396 DeleteAtom(ATOM nAtom)
397 {
398 PRTL_ATOM_TABLE AtomTable;
399 NTSTATUS Status;
400
401 if (nAtom < 0xC000)
402 {
403 return 0;
404 }
405
406 AtomTable = GetLocalAtomTable();
407
408 Status = RtlDeleteAtomFromAtomTable(AtomTable,
409 nAtom);
410 if (!NT_SUCCESS(Status))
411 {
412 SetLastErrorByStatus(Status);
413 return nAtom;
414 }
415
416 return 0;
417 }
418
419
420 /*
421 * @implemented
422 */
423 ATOM STDCALL
424 FindAtomA(LPCSTR lpString)
425 {
426 PRTL_ATOM_TABLE AtomTable;
427 UNICODE_STRING AtomName;
428 NTSTATUS Status;
429 ATOM Atom;
430
431 if (HIWORD((ULONG)lpString) == 0)
432 {
433 if ((ULONG)lpString >= 0xC000)
434 {
435 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
436 return (ATOM)0;
437 }
438 return (ATOM)LOWORD((ULONG)lpString);
439 }
440
441 AtomTable = GetLocalAtomTable();
442 RtlCreateUnicodeStringFromAsciiz(&AtomName,
443 (LPSTR)lpString);
444 Status = RtlLookupAtomInAtomTable(AtomTable,
445 AtomName.Buffer,
446 &Atom);
447 RtlFreeUnicodeString(&AtomName);
448 if (!NT_SUCCESS(Status))
449 {
450 SetLastErrorByStatus(Status);
451 return (ATOM)0;
452 }
453
454 return Atom;
455 }
456
457
458 /*
459 * @implemented
460 */
461 ATOM STDCALL
462 FindAtomW(LPCWSTR lpString)
463 {
464 PRTL_ATOM_TABLE AtomTable;
465 ATOM Atom;
466 NTSTATUS Status;
467
468 if (HIWORD((ULONG)lpString) == 0)
469 {
470 if ((ULONG)lpString >= 0xC000)
471 {
472 SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
473 return (ATOM)0;
474 }
475 return (ATOM)LOWORD((ULONG)lpString);
476 }
477
478 AtomTable = GetLocalAtomTable();
479
480 Status = RtlLookupAtomInAtomTable(AtomTable,
481 (LPWSTR)lpString,
482 &Atom);
483 if (!NT_SUCCESS(Status))
484 {
485 SetLastErrorByStatus(Status);
486 return (ATOM)0;
487 }
488
489 return Atom;
490 }
491
492
493 /*
494 * @implemented
495 */
496 UINT STDCALL
497 GetAtomNameA(ATOM nAtom,
498 LPSTR lpBuffer,
499 int nSize)
500 {
501 PRTL_ATOM_TABLE AtomTable;
502 PWCHAR Buffer;
503 UNICODE_STRING AtomNameU;
504 ANSI_STRING AtomName;
505 ULONG NameLength;
506 NTSTATUS Status;
507
508 AtomTable = GetLocalAtomTable();
509
510 NameLength = nSize * sizeof(WCHAR);
511 Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
512 HEAP_ZERO_MEMORY,
513 NameLength);
514
515 Status = RtlQueryAtomInAtomTable(AtomTable,
516 nAtom,
517 NULL,
518 NULL,
519 Buffer,
520 &NameLength);
521 if (!NT_SUCCESS(Status))
522 {
523 RtlFreeHeap(RtlGetProcessHeap(),
524 0,
525 Buffer);
526 return 0;
527 }
528
529 RtlInitUnicodeString(&AtomNameU,
530 Buffer);
531 AtomName.Buffer = lpBuffer;
532 AtomName.Length = 0;
533 AtomName.MaximumLength = nSize;
534 RtlUnicodeStringToAnsiString(&AtomName,
535 &AtomNameU,
536 FALSE);
537
538 NameLength = AtomName.Length;
539 RtlFreeHeap(RtlGetProcessHeap(),
540 0,
541 Buffer);
542
543 return NameLength;
544 }
545
546
547 /*
548 * @implemented
549 */
550 UINT STDCALL
551 GetAtomNameW(ATOM nAtom,
552 LPWSTR lpBuffer,
553 int nSize)
554 {
555 PRTL_ATOM_TABLE AtomTable;
556 ULONG NameLength;
557 NTSTATUS Status;
558
559 AtomTable = GetLocalAtomTable();
560
561 NameLength = nSize * sizeof(WCHAR);
562 Status = RtlQueryAtomInAtomTable(AtomTable,
563 nAtom,
564 NULL,
565 NULL,
566 lpBuffer,
567 &NameLength);
568 if (!NT_SUCCESS(Status))
569 {
570 return 0;
571 }
572
573 return(NameLength / sizeof(WCHAR));
574 }
575
576 /* EOF */