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