ReactOS 0.4.16-dev-257-g6aa11ac
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
24{
25 /* Create or return the local table */
27 return BaseLocalAtomTable;
28}
29
30ATOM
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,
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,
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
131ATOM
132WINAPI
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
243ATOM
244WINAPI
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
278UINT
279WINAPI
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;
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 */
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 */
432ATOM
433WINAPI
435{
436 return InternalAddAtom(FALSE, FALSE, lpString);
437}
438
439/*
440 * @implemented
441 */
442ATOM
443WINAPI
445{
446 return InternalAddAtom(FALSE, TRUE, (LPSTR)lpString);
447}
448
449/*
450 * @implemented
451 */
452ATOM
453WINAPI
455{
456 return InternalDeleteAtom(FALSE, nAtom);
457}
458
459/*
460 * @implemented
461 */
462ATOM
463WINAPI
465{
466 return InternalFindAtom(FALSE, FALSE, lpString);
467}
468
469/*
470 * @implemented
471 */
472ATOM
473WINAPI
475{
476 return InternalFindAtom(FALSE, TRUE, (LPSTR)lpString);
477}
478
479/*
480 * @implemented
481 */
482UINT
483WINAPI
486 int nSize)
487{
489}
490
491/*
492 * @implemented
493 */
494UINT
495WINAPI
498 int nSize)
499{
501 TRUE,
502 nAtom,
504 (DWORD)nSize);
505}
506
507/*
508 * @implemented
509 */
510BOOL
511WINAPI
513{
514 /* Normalize size */
515 if (nSize < 4 || nSize > 511) nSize = 37;
516
517 DPRINT("Here\n");
519}
520
521/*
522 * @implemented
523 */
524ATOM
525WINAPI
527{
528 return InternalAddAtom(TRUE, FALSE, lpString);
529}
530
531/*
532 * @implemented
533 */
534ATOM
535WINAPI
537{
538 return InternalAddAtom(TRUE, TRUE, (LPSTR)lpString);
539}
540
541/*
542 * @implemented
543 */
544ATOM
545WINAPI
547{
548 return InternalDeleteAtom(TRUE, nAtom);
549}
550
551/*
552 * @implemented
553 */
554ATOM
555WINAPI
557{
558 return InternalFindAtom(TRUE, FALSE, lpString);
559}
560
561/*
562 * @implemented
563 */
564ATOM
565WINAPI
567{
568 return InternalFindAtom(TRUE, TRUE, (LPSTR)lpString);
569
570}
571
572/*
573 * @implemented
574 */
575UINT
576WINAPI
579 int nSize)
580{
582}
583
584/*
585 * @implemented
586 */
587UINT
588WINAPI
591 int nSize)
592{
594 TRUE,
595 nAtom,
597 (DWORD)nSize);
598}
599/* EOF */
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define PtrToShort(p)
Definition: basetsd.h:88
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
_Out_ RTL_ATOM * Atom
Definition: class.h:54
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
WORD ATOM
Definition: dimm.idl:113
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
PRTL_ATOM_TABLE BaseLocalAtomTable
Definition: atom.c:17
BOOL WINAPI InitAtomTable(DWORD nSize)
Definition: atom.c:512
ATOM WINAPI FindAtomW(LPCWSTR lpString)
Definition: atom.c:566
ATOM WINAPI InternalDeleteAtom(BOOLEAN Local, ATOM Atom)
Definition: atom.c:245
UINT WINAPI GetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize)
Definition: atom.c:589
ATOM WINAPI InternalFindAtom(BOOLEAN Local, BOOLEAN Unicode, LPCSTR AtomName)
Definition: atom.c:133
ATOM WINAPI GlobalFindAtomW(LPCWSTR lpString)
Definition: atom.c:474
UINT WINAPI InternalGetAtomName(BOOLEAN Local, BOOLEAN Unicode, ATOM Atom, LPSTR AtomName, DWORD Size)
Definition: atom.c:280
PVOID WINAPI InternalInitAtomTable(VOID)
Definition: atom.c:23
UINT WINAPI GlobalGetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize)
Definition: atom.c:496
ATOM WINAPI FindAtomA(LPCSTR lpString)
Definition: atom.c:556
ATOM WINAPI AddAtomA(LPCSTR lpString)
Definition: atom.c:526
ATOM WINAPI GlobalAddAtomA(LPCSTR lpString)
Definition: atom.c:434
ATOM WINAPI DeleteAtom(ATOM nAtom)
Definition: atom.c:546
ATOM WINAPI AddAtomW(LPCWSTR lpString)
Definition: atom.c:536
UINT WINAPI GetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize)
Definition: atom.c:577
ATOM WINAPI GlobalFindAtomA(LPCSTR lpString)
Definition: atom.c:464
ATOM WINAPI InternalAddAtom(BOOLEAN Local, BOOLEAN Unicode, LPCSTR AtomName)
Definition: atom.c:32
ATOM WINAPI GlobalDeleteAtom(ATOM nAtom)
Definition: atom.c:454
UINT WINAPI GlobalGetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize)
Definition: atom.c:484
ATOM WINAPI GlobalAddAtomW(LPCWSTR lpString)
Definition: atom.c:444
@ AnsiString
Definition: dnslib.h:19
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
Status
Definition: gdiplustypes.h:25
#define NtCurrentTeb
struct atom_table ** PRTL_ATOM_TABLE
Definition: atom.c:43
unsigned int UINT
Definition: ndis.h:50
struct _ATOM_BASIC_INFORMATION ATOM_BASIC_INFORMATION
@ AtomBasicInformation
Definition: extypes.h:332
NTSYSAPI NTSTATUS NTAPI RtlAddAtomToAtomTable(_In_ PRTL_ATOM_TABLE AtomTable, _In_ PWSTR AtomName, _Out_ PRTL_ATOM Atom)
NTSYSAPI NTSTATUS NTAPI RtlLookupAtomInAtomTable(_In_ PRTL_ATOM_TABLE AtomTable, _In_ PWSTR AtomName, _Out_ PRTL_ATOM Atom)
NTSYSAPI NTSTATUS NTAPI RtlCreateAtomTable(_In_ ULONG TableSize, _Inout_ PRTL_ATOM_TABLE *AtomTable)
NTSYSAPI NTSTATUS NTAPI RtlDeleteAtomFromAtomTable(_In_ PRTL_ATOM_TABLE AtomTable, _In_ RTL_ATOM Atom)
NTSYSAPI NTSTATUS NTAPI RtlQueryAtomInAtomTable(_In_ PRTL_ATOM_TABLE AtomTable, _In_ RTL_ATOM Atom, _Out_opt_ PULONG RefCount, _Out_opt_ PULONG PinCount, _Out_opt_z_bytecap_(*NameLength) PWSTR AtomName, _Inout_opt_ PULONG NameLength)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define UNICODE_NULL
NTSTATUS NTAPI NtQueryInformationAtom(RTL_ATOM Atom, ATOM_INFORMATION_CLASS AtomInformationClass, PVOID AtomInformation, ULONG AtomInformationLength, PULONG ReturnLength)
Definition: atom.c:365
NTSTATUS NTAPI NtDeleteAtom(IN RTL_ATOM Atom)
Definition: atom.c:206
NTSTATUS NTAPI NtAddAtom(IN PWSTR AtomName, IN ULONG AtomNameLength, OUT PRTL_ATOM Atom)
Definition: atom.c:86
NTSTATUS NTAPI NtFindAtom(IN PWSTR AtomName, IN ULONG AtomNameLength, OUT PRTL_ATOM Atom)
Definition: atom.c:243
unsigned short USHORT
Definition: pedump.c:61
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:167
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define DPRINT
Definition: sndvol32.h:73
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
#define INVALID_ATOM
Definition: winbase.h:476
#define MAXINTATOM
Definition: winbase.h:475
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2109
#define WINAPI
Definition: msvc.h:6
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185