ReactOS  0.4.15-dev-4927-gfe8f806
atom.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for atom.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

PRTL_ATOM_TABLE NTAPI ExpGetGlobalAtomTable (VOID)
 
NTSTATUS NTAPI NtAddAtom (IN PWSTR AtomName, IN ULONG AtomNameLength, OUT PRTL_ATOM Atom)
 
NTSTATUS NTAPI NtDeleteAtom (IN RTL_ATOM Atom)
 
NTSTATUS NTAPI NtFindAtom (IN PWSTR AtomName, IN ULONG AtomNameLength, OUT PRTL_ATOM Atom)
 
NTSTATUS NTAPI NtQueryInformationAtom (RTL_ATOM Atom, ATOM_INFORMATION_CLASS AtomInformationClass, PVOID AtomInformation, ULONG AtomInformationLength, PULONG ReturnLength)
 

Variables

PRTL_ATOM_TABLE GlobalAtomTable
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file atom.c.

Function Documentation

◆ ExpGetGlobalAtomTable()

PRTL_ATOM_TABLE NTAPI ExpGetGlobalAtomTable ( VOID  )

Definition at line 42 of file atom.c.

43 {
45 
46  /* Return it if we have one */
47  if (GlobalAtomTable) return GlobalAtomTable;
48 
49  /* Create it */
51 
52  /* If we couldn't create it, return NULL */
53  if (!NT_SUCCESS(Status)) return NULL;
54 
55  /* Return the newly created one */
56  return GlobalAtomTable;
57 }
LONG NTSTATUS
Definition: precomp.h:26
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI RtlCreateAtomTable(IN ULONG TableSize, IN OUT PRTL_ATOM_TABLE *AtomTable)
Definition: atom.c:150
PRTL_ATOM_TABLE GlobalAtomTable
Definition: atom.c:25
#define NULL
Definition: types.h:112

Referenced by NtAddAtom(), NtDeleteAtom(), NtFindAtom(), and NtQueryInformationAtom().

◆ NtAddAtom()

NTSTATUS NTAPI NtAddAtom ( IN PWSTR  AtomName,
IN ULONG  AtomNameLength,
OUT PRTL_ATOM  Atom 
)

Definition at line 86 of file atom.c.

89 {
93  LPWSTR CapturedName;
94  ULONG CapturedSize;
95  RTL_ATOM SafeAtom;
96  PAGED_CODE();
97 
98  /* Check for the table */
99  if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
100 
101  /* Check for valid name */
102  if (AtomNameLength > (RTL_MAXIMUM_ATOM_LENGTH * sizeof(WCHAR)))
103  {
104  /* Fail */
105  DPRINT1("Atom name too long\n");
107  }
108 
109  /* Check if we're called from user-mode or kernel-mode */
110  if (PreviousMode == KernelMode)
111  {
112  /* Re-use the given name if kernel mode */
113  CapturedName = AtomName;
114  }
115  else
116  {
117  /* Check if we have a name */
118  if (AtomName)
119  {
120  /* Allocate an aligned buffer + the null char */
121  CapturedSize = ((AtomNameLength + sizeof(WCHAR)) &
122  ~(sizeof(WCHAR) -1));
123  CapturedName = ExAllocatePoolWithTag(PagedPool,
124  CapturedSize,
125  TAG_ATOM);
126 
127  if (!CapturedName)
128  {
129  /* Fail the call */
131  }
132 
133  /* Enter SEH */
134  _SEH2_TRY
135  {
136  /* Probe the atom */
137  ProbeForRead(AtomName, AtomNameLength, sizeof(WCHAR));
138 
139  /* Copy the name and null-terminate it */
140  RtlCopyMemory(CapturedName, AtomName, AtomNameLength);
141  CapturedName[AtomNameLength / sizeof(WCHAR)] = UNICODE_NULL;
142 
143  /* Probe the atom too */
145  }
147  {
148  /* Return the exception code */
150  }
151  _SEH2_END;
152  }
153  else
154  {
155  /* No name */
156  CapturedName = NULL;
157  }
158  }
159 
160  /* Call the runtime function */
161  Status = RtlAddAtomToAtomTable(AtomTable, CapturedName, &SafeAtom);
162  if (NT_SUCCESS(Status) && (Atom))
163  {
164  /* Success and caller wants the atom back.. .enter SEH */
165  _SEH2_TRY
166  {
167  /* Return the atom */
168  *Atom = SafeAtom;
169  }
171  {
172  /* Get the exception code */
174  }
175  _SEH2_END;
176  }
177 
178  /* If we captured anything, free it */
179  if ((CapturedName != NULL) && (CapturedName != AtomName))
180  ExFreePoolWithTag(CapturedName, TAG_ATOM);
181 
182  /* Return to caller */
183  return Status;
184 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
unsigned short RTL_ATOM
Definition: atom.c:42
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define ProbeForWriteUshort(Ptr)
Definition: probe.h:34
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3063
#define TAG_ATOM
Definition: tag.h:29
_SEH2_TRY
Definition: create.c:4226
#define UNICODE_NULL
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define RTL_MAXIMUM_ATOM_LENGTH
Definition: rtltypes.h:36
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Out_ RTL_ATOM * Atom
Definition: class.h:54
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
struct atom_table ** PRTL_ATOM_TABLE
Definition: atom.c:43
_SEH2_END
Definition: create.c:4400
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define NULL
Definition: types.h:112
PRTL_ATOM_TABLE NTAPI ExpGetGlobalAtomTable(VOID)
Definition: atom.c:42
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
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
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define PAGED_CODE()

Referenced by InitUserAtoms(), and InternalAddAtom().

◆ NtDeleteAtom()

NTSTATUS NTAPI NtDeleteAtom ( IN RTL_ATOM  Atom)

Definition at line 206 of file atom.c.

207 {
209  PAGED_CODE();
210 
211  /* Check for valid table */
212  if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
213 
214  /* Call worker function */
215  return RtlDeleteAtomFromAtomTable(AtomTable, Atom);
216 }
NTSTATUS NTAPI RtlDeleteAtomFromAtomTable(IN PRTL_ATOM_TABLE AtomTable, IN RTL_ATOM Atom)
Definition: atom.c:426
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_Out_ RTL_ATOM * Atom
Definition: class.h:54
struct atom_table ** PRTL_ATOM_TABLE
Definition: atom.c:43
#define NULL
Definition: types.h:112
PRTL_ATOM_TABLE NTAPI ExpGetGlobalAtomTable(VOID)
Definition: atom.c:42
#define PAGED_CODE()

Referenced by InternalDeleteAtom().

◆ NtFindAtom()

NTSTATUS NTAPI NtFindAtom ( IN PWSTR  AtomName,
IN ULONG  AtomNameLength,
OUT PRTL_ATOM  Atom 
)

Definition at line 243 of file atom.c.

246 {
250  _SEH2_VOLATILE LPWSTR CapturedName;
251  ULONG CapturedSize;
252  RTL_ATOM SafeAtom;
253  PAGED_CODE();
254 
255  /* Check for the table */
256  if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
257 
258  /* Check for valid name */
259  if (AtomNameLength > (RTL_MAXIMUM_ATOM_LENGTH * sizeof(WCHAR)))
260  {
261  /* Fail */
262  DPRINT1("Atom name too long\n");
264  }
265 
266  /* Re-use the given name if kernel mode or no atom name */
267  CapturedName = AtomName;
268 
269  /* Check if we're called from user-mode*/
270  if (PreviousMode != KernelMode)
271  {
272  /* Enter SEH */
273  _SEH2_TRY
274  {
275  /* Check if we have a name */
276  if (AtomName)
277  {
278  /* Probe the atom */
279  ProbeForRead(AtomName, AtomNameLength, sizeof(WCHAR));
280 
281  /* Allocate an aligned buffer + the null char */
282  CapturedSize = ((AtomNameLength + sizeof(WCHAR)) &~
283  (sizeof(WCHAR) -1));
284  CapturedName = ExAllocatePoolWithQuotaTag(PagedPool,
285  CapturedSize,
286  TAG_ATOM);
287  /* Copy the name and null-terminate it */
288  RtlCopyMemory(CapturedName, AtomName, AtomNameLength);
289  CapturedName[AtomNameLength / sizeof(WCHAR)] = UNICODE_NULL;
290 
291  /* Probe the atom too */
293  }
294  }
296  {
297  if (CapturedName != AtomName)
298  {
299  ExFreePoolWithTag(CapturedName, TAG_ATOM);
300  }
301 
302  /* Return the exception code */
304  }
305  _SEH2_END;
306  }
307 
308  /* Call the runtime function */
309  Status = RtlLookupAtomInAtomTable(AtomTable, CapturedName, &SafeAtom);
310  if (NT_SUCCESS(Status) && (Atom))
311  {
312  /* Success and caller wants the atom back... enter SEH */
313  _SEH2_TRY
314  {
315  /* Return the atom */
316  *Atom = SafeAtom;
317  }
319  {
321  }
322  _SEH2_END;
323  }
324 
325  /* If we captured anything, free it */
326  if ((CapturedName) && (CapturedName != AtomName))
327  ExFreePoolWithTag(CapturedName, TAG_ATOM);
328 
329  /* Return to caller */
330  return Status;
331 }
unsigned short RTL_ATOM
Definition: atom.c:42
PVOID NTAPI ExAllocatePoolWithQuotaTag(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: expool.c:2984
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define ProbeForWriteUshort(Ptr)
Definition: probe.h:34
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3063
#define TAG_ATOM
Definition: tag.h:29
_SEH2_TRY
Definition: create.c:4226
#define UNICODE_NULL
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define RTL_MAXIMUM_ATOM_LENGTH
Definition: rtltypes.h:36
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
_Out_ RTL_ATOM * Atom
Definition: class.h:54
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
struct atom_table ** PRTL_ATOM_TABLE
Definition: atom.c:43
#define _SEH2_VOLATILE
Definition: pseh2_64.h:169
_SEH2_END
Definition: create.c:4400
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define NULL
Definition: types.h:112
PRTL_ATOM_TABLE NTAPI ExpGetGlobalAtomTable(VOID)
Definition: atom.c:42
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
NTSTATUS NTAPI RtlLookupAtomInAtomTable(IN PRTL_ATOM_TABLE AtomTable, IN PWSTR AtomName, OUT PRTL_ATOM Atom)
Definition: atom.c:495
#define PAGED_CODE()

Referenced by InternalFindAtom().

◆ NtQueryInformationAtom()

NTSTATUS NTAPI NtQueryInformationAtom ( RTL_ATOM  Atom,
ATOM_INFORMATION_CLASS  AtomInformationClass,
PVOID  AtomInformation,
ULONG  AtomInformationLength,
PULONG  ReturnLength 
)

Definition at line 365 of file atom.c.

370 {
372  PATOM_BASIC_INFORMATION BasicInformation = AtomInformation;
373  PATOM_TABLE_INFORMATION TableInformation = AtomInformation;
375  ULONG Flags, UsageCount, NameLength, RequiredLength = 0;
377 
378  PAGED_CODE();
379 
380  /* Check for valid table */
381  if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
382 
384 
385  _SEH2_TRY
386  {
387  /* Probe the parameters */
388  if (PreviousMode != KernelMode)
389  {
390  ProbeForWrite(AtomInformation,
391  AtomInformationLength,
392  sizeof(ULONG));
393 
394  if (ReturnLength != NULL)
395  {
397  }
398  }
399 
400  /* Choose class */
401  switch (AtomInformationClass)
402  {
403  /* Caller requested info about an atom */
405 
406  /* Size check */
408  if (RequiredLength > AtomInformationLength)
409  {
410  /* Fail */
411  DPRINT1("Buffer too small\n");
413  _SEH2_LEAVE;
414  }
415 
416  /* Prepare query */
417  UsageCount = 0;
418  NameLength = AtomInformationLength - RequiredLength;
419  BasicInformation->Name[0] = UNICODE_NULL;
420 
421  /* Query the data */
422  Status = RtlQueryAtomInAtomTable(AtomTable,
423  Atom,
424  &UsageCount,
425  &Flags,
426  BasicInformation->Name,
427  &NameLength);
428  if (NT_SUCCESS(Status))
429  {
430  /* Return data */
431  BasicInformation->UsageCount = (USHORT)UsageCount;
432  BasicInformation->Flags = (USHORT)Flags;
433  BasicInformation->NameLength = (USHORT)NameLength;
434  RequiredLength += NameLength + sizeof(WCHAR);
435  }
436  break;
437 
438  /* Caller requested info about an Atom Table */
440 
441  /* Size check */
443  if (RequiredLength > AtomInformationLength)
444  {
445  /* Fail */
446  DPRINT1("Buffer too small\n");
448  _SEH2_LEAVE;
449  }
450 
451  /* Query the data */
453  (AtomInformationLength - RequiredLength) /
454  sizeof(RTL_ATOM),
455  &TableInformation->NumberOfAtoms,
456  TableInformation->Atoms);
457  if (NT_SUCCESS(Status))
458  {
459  /* Update the return length */
460  RequiredLength += TableInformation->NumberOfAtoms * sizeof(RTL_ATOM);
461  }
462  break;
463 
464  /* Caller was on crack */
465  default:
466 
467  /* Unrecognized class */
469  break;
470  }
471 
472  /* Return the required size */
473  if (ReturnLength != NULL)
474  {
476  }
477  }
479  {
481  }
482  _SEH2_END;
483 
484  /* Return to caller */
485  return Status;
486 }
#define ProbeForWriteUlong(Ptr)
Definition: probe.h:36
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
unsigned short RTL_ATOM
Definition: atom.c:42
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
LONG NTSTATUS
Definition: precomp.h:26
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3063
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_SEH2_TRY
Definition: create.c:4226
#define UNICODE_NULL
NTSTATUS NTAPI RtlQueryAtomInAtomTable(PRTL_ATOM_TABLE AtomTable, RTL_ATOM Atom, PULONG RefCount, PULONG PinCount, PWSTR AtomName, PULONG NameLength)
Definition: atom.c:600
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
_Out_ RTL_ATOM * Atom
Definition: class.h:54
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
struct atom_table ** PRTL_ATOM_TABLE
Definition: atom.c:43
_SEH2_END
Definition: create.c:4400
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
unsigned short USHORT
Definition: pedump.c:61
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_In_ ULONG _Out_opt_ PULONG RequiredLength
Definition: wmifuncs.h:29
#define NULL
Definition: types.h:112
PRTL_ATOM_TABLE NTAPI ExpGetGlobalAtomTable(VOID)
Definition: atom.c:42
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
NTSTATUS NTAPI RtlQueryAtomListInAtomTable(IN PRTL_ATOM_TABLE AtomTable, IN ULONG MaxAtomCount, OUT ULONG *AtomCount, OUT RTL_ATOM *AtomList)
Definition: atom.c:704
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_LEAVE
Definition: filesup.c:20
#define PAGED_CODE()

Referenced by InternalGetAtomName().

Variable Documentation

◆ GlobalAtomTable

PRTL_ATOM_TABLE GlobalAtomTable

Definition at line 25 of file atom.c.

Referenced by ExpGetGlobalAtomTable().