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