ReactOS  0.4.13-dev-92-gf251225
atom.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * FILE: dll/win32/kernel32/client/atom.c
5  * PURPOSE: Atom functions
6  * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 #include <k32.h>
11 
12 #define NDEBUG
13 #include <debug.h>
14 
15 /* GLOBALS *******************************************************************/
16 
18 
19 /* FUNCTIONS *****************************************************************/
20 
21 PVOID
22 WINAPI
24 {
25  /* Create or return the local table */
27  return BaseLocalAtomTable;
28 }
29 
30 ATOM
31 WINAPI
33  BOOLEAN Unicode,
34  LPCSTR AtomName)
35 {
39  PUNICODE_STRING AtomNameString;
41 
42  /* Check if it's an integer atom */
43  if ((ULONG_PTR)AtomName <= 0xFFFF)
44  {
45  /* Convert the name to an atom */
46  Atom = (ATOM)PtrToShort((PVOID)AtomName);
47  if (Atom >= MAXINTATOM)
48  {
49  /* Fail, atom number too large */
51  return INVALID_ATOM;
52  }
53 
54  /* Return it */
55  return Atom;
56  }
57  else
58  {
59  /* Check if this is a unicode atom */
60  if (Unicode)
61  {
62  /* Use a unicode string */
63  AtomNameString = &UnicodeString;
64  RtlInitUnicodeString(AtomNameString, (LPWSTR)AtomName);
66  }
67  else
68  {
69  /* Use an ansi string */
70  RtlInitAnsiString(&AnsiString, AtomName );
71 
72  /* Check if we can abuse the TEB */
73  if (AnsiString.MaximumLength > 260)
74  {
75  /* We can't, allocate a new string */
76  AtomNameString = &UnicodeString;
77  Status = RtlAnsiStringToUnicodeString(AtomNameString,
78  &AnsiString,
79  TRUE);
80  }
81  else
82  {
83  /* We can! Get the TEB String */
84  AtomNameString = &NtCurrentTeb()->StaticUnicodeString;
85 
86  /* Convert it into the TEB */
87  Status = RtlAnsiStringToUnicodeString(AtomNameString,
88  &AnsiString,
89  FALSE);
90  }
91  }
92 
93  /* Check for failure */
94  if (!NT_SUCCESS(Status))
95  {
97  return Atom;
98  }
99  }
100 
101  /* Check if we're doing local add */
102  if (Local)
103  {
104  /* Do a local add */
106  AtomNameString->Buffer,
107  &Atom);
108  }
109  else
110  {
111  /* Do a global add */
112  Status = NtAddAtom(AtomNameString->Buffer,
113  AtomNameString->Length,
114  &Atom);
115  }
116 
117  /* Check for failure */
119 
120  /* Check if we were non-static ANSI */
121  if (!(Unicode) && (AtomNameString == &UnicodeString))
122  {
123  /* Free the allocated buffer */
124  RtlFreeUnicodeString(AtomNameString);
125  }
126 
127  /* Return the atom */
128  return Atom;
129 }
130 
131 ATOM
132 WINAPI
134  BOOLEAN Unicode,
135  LPCSTR AtomName)
136 {
140  PUNICODE_STRING AtomNameString;
142 
143  /* Check if it's an integer atom */
144  if ((ULONG_PTR)AtomName <= 0xFFFF)
145  {
146  /* Convert the name to an atom */
147  Atom = (ATOM)PtrToShort((PVOID)AtomName);
148  if (Atom >= MAXINTATOM)
149  {
150  /* Fail, atom number too large */
152  DPRINT1("Invalid atom\n");
153  }
154 
155  /* Return it */
156  return Atom;
157  }
158  else
159  {
160  /* Check if this is a unicode atom */
161  if (Unicode)
162  {
163  /* Use a unicode string */
164  AtomNameString = &UnicodeString;
165  RtlInitUnicodeString(AtomNameString, (LPWSTR)AtomName);
167  }
168  else
169  {
170  /* Use an ansi string */
171  RtlInitAnsiString(&AnsiString, AtomName);
172 
173  /* Check if we can abuse the TEB */
174  if (AnsiString.MaximumLength > 260)
175  {
176  /* We can't, allocate a new string */
177  AtomNameString = &UnicodeString;
178  Status = RtlAnsiStringToUnicodeString(AtomNameString,
179  &AnsiString,
180  TRUE);
181  }
182  else
183  {
184  /* We can! Get the TEB String */
185  AtomNameString = &NtCurrentTeb()->StaticUnicodeString;
186 
187  /* Convert it into the TEB */
188  Status = RtlAnsiStringToUnicodeString(AtomNameString,
189  &AnsiString,
190  FALSE);
191  }
192  }
193 
194  /* Check for failure */
195  if (!NT_SUCCESS(Status))
196  {
197  DPRINT1("Failed\n");
199  return Atom;
200  }
201  }
202 
203  /* Check if we're doing local lookup */
204  if (Local)
205  {
206  /* Do a local lookup */
208  AtomNameString->Buffer,
209  &Atom);
210  }
211  else
212  {
213  /* Do a global search */
214  if (!AtomNameString->Length)
215  {
216  /* This is illegal in win32 */
217  DPRINT1("No name given\n");
219  }
220  else
221  {
222  /* Call the global function */
223  Status = NtFindAtom(AtomNameString->Buffer,
224  AtomNameString->Length,
225  &Atom);
226  }
227  }
228 
229  /* Check for failure */
231 
232  /* Check if we were non-static ANSI */
233  if (!(Unicode) && (AtomNameString == &UnicodeString))
234  {
235  /* Free the allocated buffer */
236  RtlFreeUnicodeString(AtomNameString);
237  }
238 
239  /* Return the atom */
240  return Atom;
241 }
242 
243 ATOM
244 WINAPI
246  ATOM Atom)
247 {
249 
250  /* Validate it */
251  if (Atom >= MAXINTATOM)
252  {
253  /* Check if it's a local delete */
254  if (Local)
255  {
256  /* Delete it locally */
258  }
259  else
260  {
261  /* Delete it globall */
263  }
264 
265  /* Check for success */
266  if (!NT_SUCCESS(Status))
267  {
268  /* Fail */
270  return INVALID_ATOM;
271  }
272  }
273 
274  /* Return failure */
275  return 0;
276 }
277 
278 UINT
279 WINAPI
281  BOOLEAN Unicode,
282  ATOM Atom,
283  LPSTR AtomName,
284  DWORD Size)
285 {
287  DWORD RetVal = 0;
290  PVOID TempBuffer = NULL;
291  PWSTR AtomNameString;
292  ULONG AtomInfoLength;
293  ULONG AtomNameLength;
294  PATOM_BASIC_INFORMATION AtomInfo;
295 
296  /* Normalize the size as not to overflow */
297  if (!Unicode && Size > 0x7000) Size = 0x7000;
298 
299  /* Make sure it's valid too */
300  if (!Size)
301  {
303  return 0;
304  }
305  if (!Atom)
306  {
308  return 0;
309  }
310 
311  /* Check if this is a global query */
312  if (Local)
313  {
314  /* Set the query length */
315  AtomNameLength = Size * sizeof(WCHAR);
316 
317  /* If it's unicode, just keep the name */
318  if (Unicode)
319  {
320  AtomNameString = (PWSTR)AtomName;
321  }
322  else
323  {
324  /* Allocate memory for the ansi buffer */
325  TempBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
326  0,
327  AtomNameLength);
328  AtomNameString = TempBuffer;
329  }
330 
331  /* Query the name */
333  Atom,
334  NULL,
335  NULL,
336  AtomNameString,
337  &AtomNameLength);
338  }
339  else
340  {
341  /* We're going to do a global query, so allocate a buffer */
342  AtomInfoLength = sizeof(ATOM_BASIC_INFORMATION) +
343  (Size * sizeof(WCHAR));
344  AtomInfo = TempBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
345  0,
346  AtomInfoLength);
347 
348  if (!AtomInfo)
349  {
351  return 0;
352  }
353 
354  /* Query the name */
357  AtomInfo,
358  AtomInfoLength,
359  &AtomInfoLength);
360  if (NT_SUCCESS(Status))
361  {
362  /* Success. Update the length and get the name */
363  AtomNameLength = (ULONG)AtomInfo->NameLength;
364  AtomNameString = AtomInfo->Name;
365  }
366  }
367 
368  /* Check for global success */
369  if (NT_SUCCESS(Status))
370  {
371  /* Check if it was unicode */
372  if (Unicode)
373  {
374  /* We return the length in chars */
375  RetVal = AtomNameLength / sizeof(WCHAR);
376 
377  /* Copy the memory if this was a global query */
378  if (AtomNameString != (PWSTR)AtomName)
379  {
380  RtlMoveMemory(AtomName, AtomNameString, AtomNameLength);
381  }
382 
383  /* And null-terminate it if the buffer was too large */
384  if (RetVal < Size)
385  {
386  ((PWCHAR)AtomName)[RetVal] = UNICODE_NULL;
387  }
388  }
389  else
390  {
391  /* First create a unicode string with our data */
392  UnicodeString.Buffer = AtomNameString;
393  UnicodeString.Length = (USHORT)AtomNameLength;
394  UnicodeString.MaximumLength = (USHORT)(UnicodeString.Length +
395  sizeof(WCHAR));
396 
397  /* Now prepare an ansi string for conversion */
398  AnsiString.Buffer = AtomName;
399  AnsiString.Length = 0;
400  AnsiString.MaximumLength = (USHORT)Size;
401 
402  /* Convert it */
404  &UnicodeString,
405  FALSE);
406 
407  /* Return the length */
408  if (NT_SUCCESS(Status)) RetVal = AnsiString.Length;
409  }
410  }
411 
412  /* Free the temporary buffer if we have one */
413  if (TempBuffer) RtlFreeHeap(RtlGetProcessHeap(), 0, TempBuffer);
414 
415  /* Check for failure */
416  if (!NT_SUCCESS(Status))
417  {
418  /* Fail */
419  DPRINT("Failed: %lx\n", Status);
421  }
422 
423  /* Return length */
424  return RetVal;
425 }
426 
427 /* FUNCTIONS *****************************************************************/
428 
429 /*
430  * @implemented
431  */
432 ATOM
433 WINAPI
435 {
436  return InternalAddAtom(FALSE, FALSE, lpString);
437 }
438 
439 /*
440  * @implemented
441  */
442 ATOM
443 WINAPI
445 {
446  return InternalAddAtom(FALSE, TRUE, (LPSTR)lpString);
447 }
448 
449 /*
450  * @implemented
451  */
452 ATOM
453 WINAPI
455 {
456  return InternalDeleteAtom(FALSE, nAtom);
457 }
458 
459 /*
460  * @implemented
461  */
462 ATOM
463 WINAPI
465 {
466  return InternalFindAtom(FALSE, FALSE, lpString);
467 }
468 
469 /*
470  * @implemented
471  */
472 ATOM
473 WINAPI
475 {
476  return InternalFindAtom(FALSE, TRUE, (LPSTR)lpString);
477 }
478 
479 /*
480  * @implemented
481  */
482 UINT
483 WINAPI
485  LPSTR lpBuffer,
486  int nSize)
487 {
488  return InternalGetAtomName(FALSE, FALSE, nAtom, lpBuffer, (DWORD)nSize);
489 }
490 
491 /*
492  * @implemented
493  */
494 UINT
495 WINAPI
498  int nSize)
499 {
500  return InternalGetAtomName(FALSE,
501  TRUE,
502  nAtom,
503  (LPSTR)lpBuffer,
504  (DWORD)nSize);
505 }
506 
507 /*
508  * @implemented
509  */
510 BOOL
511 WINAPI
513 {
514  /* Normalize size */
515  if (nSize < 4 || nSize > 511) nSize = 37;
516 
517  DPRINT("Here\n");
519 }
520 
521 /*
522  * @implemented
523  */
524 ATOM
525 WINAPI
526 AddAtomA(LPCSTR lpString)
527 {
528  return InternalAddAtom(TRUE, FALSE, lpString);
529 }
530 
531 /*
532  * @implemented
533  */
534 ATOM
535 WINAPI
536 AddAtomW(LPCWSTR lpString)
537 {
538  return InternalAddAtom(TRUE, TRUE, (LPSTR)lpString);
539 }
540 
541 /*
542  * @implemented
543  */
544 ATOM
545 WINAPI
547 {
548  return InternalDeleteAtom(TRUE, nAtom);
549 }
550 
551 /*
552  * @implemented
553  */
554 ATOM
555 WINAPI
556 FindAtomA(LPCSTR lpString)
557 {
558  return InternalFindAtom(TRUE, FALSE, lpString);
559 }
560 
561 /*
562  * @implemented
563  */
564 ATOM
565 WINAPI
567 {
568  return InternalFindAtom(TRUE, TRUE, (LPSTR)lpString);
569 
570 }
571 
572 /*
573  * @implemented
574  */
575 UINT
576 WINAPI
578  LPSTR lpBuffer,
579  int nSize)
580 {
581  return InternalGetAtomName(TRUE, FALSE, nAtom, lpBuffer, (DWORD)nSize);
582 }
583 
584 /*
585  * @implemented
586  */
587 UINT
588 WINAPI
591  int nSize)
592 {
593  return InternalGetAtomName(TRUE,
594  TRUE,
595  nAtom,
596  (LPSTR)lpBuffer,
597  (DWORD)nSize);
598 }
599 /* EOF */
UINT WINAPI GetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize)
Definition: atom.c:577
ATOM WINAPI GlobalDeleteAtom(ATOM nAtom)
Definition: atom.c:454
static PWSTR
Definition: atom.c:55
NTSTATUS NTAPI NtQueryInformationAtom(RTL_ATOM Atom, ATOM_INFORMATION_CLASS AtomInformationClass, PVOID AtomInformation, ULONG AtomInformationLength, PULONG ReturnLength)
Definition: atom.c:370
#define TRUE
Definition: types.h:120
*BytesInUnicodeString PWCH UnicodeString
Definition: rtlfuncs.h:1980
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
WORD ATOM
Definition: dimm.idl:113
NTSTATUS NTAPI NtDeleteAtom(IN RTL_ATOM Atom)
Definition: atom.c:208
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:54
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2024
LONG NTSTATUS
Definition: precomp.h:26
#define PtrToShort(p)
Definition: basetsd.h:88
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
UINT WINAPI GetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize)
Definition: atom.c:589
ATOM WINAPI GlobalAddAtomA(LPCSTR lpString)
Definition: atom.c:434
ATOM WINAPI GlobalFindAtomW(LPCWSTR lpString)
Definition: atom.c:474
uint16_t * PWCHAR
Definition: typedefs.h:54
char * LPSTR
Definition: xmlstorage.h:182
_Out_ RTL_ATOM * Atom
Definition: class.h:54
ATOM WINAPI InternalFindAtom(BOOLEAN Local, BOOLEAN Unicode, LPCSTR AtomName)
Definition: atom.c:133
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
ATOM WINAPI InternalAddAtom(BOOLEAN Local, BOOLEAN Unicode, LPCSTR AtomName)
Definition: atom.c:32
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define UNICODE_NULL
ATOM WINAPI DeleteAtom(ATOM nAtom)
Definition: atom.c:546
unsigned int BOOL
Definition: ntddk_ex.h:94
NTSTATUS NTAPI RtlQueryAtomInAtomTable(PRTL_ATOM_TABLE AtomTable, RTL_ATOM Atom, PULONG RefCount, PULONG PinCount, PWSTR AtomName, PULONG NameLength)
Definition: atom.c:600
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
#define MAXINTATOM
Definition: winbase.h:430
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
ATOM WINAPI AddAtomW(LPCWSTR lpString)
Definition: atom.c:536
void DPRINT(...)
Definition: polytest.cpp:61
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
const char * LPCSTR
Definition: xmlstorage.h:183
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
static ULONG
Definition: atom.c:57
UINT WINAPI GlobalGetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize)
Definition: atom.c:496
__wchar_t WCHAR
Definition: xmlstorage.h:180
NTSTATUS NTAPI RtlDeleteAtomFromAtomTable(IN PRTL_ATOM_TABLE AtomTable, IN RTL_ATOM Atom)
Definition: atom.c:426
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ATOM WINAPI FindAtomW(LPCWSTR lpString)
Definition: atom.c:566
#define WINAPI
Definition: msvc.h:8
ATOM WINAPI InternalDeleteAtom(BOOLEAN Local, ATOM Atom)
Definition: atom.c:245
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL WINAPI InitAtomTable(DWORD nSize)
Definition: atom.c:512
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSTATUS NTAPI NtAddAtom(IN PWSTR AtomName, IN ULONG AtomNameLength, OUT PRTL_ATOM Atom)
Definition: atom.c:88
ATOM WINAPI AddAtomA(LPCSTR lpString)
Definition: atom.c:526
ATOM WINAPI GlobalFindAtomA(LPCSTR lpString)
Definition: atom.c:464
PRTL_ATOM_TABLE BaseLocalAtomTable
Definition: atom.c:17
struct _ATOM_BASIC_INFORMATION ATOM_BASIC_INFORMATION
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
NTSTATUS NTAPI RtlCreateAtomTable(IN ULONG TableSize, IN OUT PRTL_ATOM_TABLE *AtomTable)
Definition: atom.c:150
struct atom_table ** PRTL_ATOM_TABLE
Definition: atom.c:43
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
NTSTATUS NTAPI NtFindAtom(IN PWSTR AtomName, IN ULONG AtomNameLength, OUT PRTL_ATOM Atom)
Definition: atom.c:245
unsigned int UINT
Definition: ndis.h:50
ATOM WINAPI GlobalAddAtomW(LPCWSTR lpString)
Definition: atom.c:444
UINT WINAPI InternalGetAtomName(BOOLEAN Local, BOOLEAN Unicode, ATOM Atom, LPSTR AtomName, DWORD Size)
Definition: atom.c:280
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
UINT WINAPI GlobalGetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize)
Definition: atom.c:484
ATOM WINAPI FindAtomA(LPCSTR lpString)
Definition: atom.c:556
#define INVALID_ATOM
Definition: winbase.h:431
WCHAR * LPWSTR
Definition: xmlstorage.h:184
NTSTATUS NTAPI RtlAddAtomToAtomTable(IN PRTL_ATOM_TABLE AtomTable, IN PWSTR AtomName, OUT PRTL_ATOM Atom)
Definition: atom.c:308
return STATUS_SUCCESS
Definition: btrfs.c:2725
NTSTATUS NTAPI RtlLookupAtomInAtomTable(IN PRTL_ATOM_TABLE AtomTable, IN PWSTR AtomName, OUT PRTL_ATOM Atom)
Definition: atom.c:495
PVOID WINAPI InternalInitAtomTable(VOID)
Definition: atom.c:23