1c2c66affSColin Finck /*
2c2c66affSColin Finck * PROJECT: ReactOS Kernel
3c2c66affSColin Finck * COPYRIGHT: GPL - See COPYING in the top level directory
4c2c66affSColin Finck * FILE: ntoskrnl/ex/atom.c
5c2c66affSColin Finck * PURPOSE: Executive Atom Functions
6c2c66affSColin Finck * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7c2c66affSColin Finck * Gunnar Dalsnes
8c2c66affSColin Finck */
9c2c66affSColin Finck
10c2c66affSColin Finck /* INCLUDES *****************************************************************/
11c2c66affSColin Finck
12c2c66affSColin Finck #include <ntoskrnl.h>
13c2c66affSColin Finck #define NDEBUG
14c2c66affSColin Finck #include <debug.h>
15c2c66affSColin Finck
16c2c66affSColin Finck /* GLOBALS ****************************************************************/
17c2c66affSColin Finck
18c2c66affSColin Finck /*
19c2c66affSColin Finck * FIXME: this is WRONG! The global atom table should live in the WinSta struct
20c2c66affSColin Finck * and accessed through a win32k callout (received in PsEstablishWin32Callouts)
21c2c66affSColin Finck * NOTE: There is a session/win32k global atom table also, but its private to
22c2c66affSColin Finck * win32k. Its used for RegisterWindowMessage() and for window classes.
23c2c66affSColin Finck * -Gunnar
24c2c66affSColin Finck */
25c2c66affSColin Finck PRTL_ATOM_TABLE GlobalAtomTable;
26c2c66affSColin Finck
27c2c66affSColin Finck /* PRIVATE FUNCTIONS *********************************************************/
28c2c66affSColin Finck
29c2c66affSColin Finck /*++
30c2c66affSColin Finck * @name ExpGetGlobalAtomTable
31c2c66affSColin Finck *
32c2c66affSColin Finck * Gets pointer to a global atom table, creates it if not already created
33c2c66affSColin Finck *
34c2c66affSColin Finck * @return Pointer to the RTL_ATOM_TABLE, or NULL if it's impossible
35c2c66affSColin Finck * to create atom table
36c2c66affSColin Finck *
37c2c66affSColin Finck * @remarks Internal function
38c2c66affSColin Finck *
39c2c66affSColin Finck *--*/
40c2c66affSColin Finck PRTL_ATOM_TABLE
41c2c66affSColin Finck NTAPI
ExpGetGlobalAtomTable(VOID)42c2c66affSColin Finck ExpGetGlobalAtomTable(VOID)
43c2c66affSColin Finck {
44c2c66affSColin Finck NTSTATUS Status;
45c2c66affSColin Finck
46c2c66affSColin Finck /* Return it if we have one */
47c2c66affSColin Finck if (GlobalAtomTable) return GlobalAtomTable;
48c2c66affSColin Finck
49c2c66affSColin Finck /* Create it */
50c2c66affSColin Finck Status = RtlCreateAtomTable(37, &GlobalAtomTable);
51c2c66affSColin Finck
52c2c66affSColin Finck /* If we couldn't create it, return NULL */
53c2c66affSColin Finck if (!NT_SUCCESS(Status)) return NULL;
54c2c66affSColin Finck
55c2c66affSColin Finck /* Return the newly created one */
56c2c66affSColin Finck return GlobalAtomTable;
57c2c66affSColin Finck }
58c2c66affSColin Finck
59c2c66affSColin Finck /* FUNCTIONS ****************************************************************/
60c2c66affSColin Finck
61c2c66affSColin Finck /*++
62c2c66affSColin Finck * @name NtAddAtom
63c2c66affSColin Finck * @implemented
64c2c66affSColin Finck *
65c2c66affSColin Finck * Function NtAddAtom creates new Atom in Global Atom Table. If Atom
66c2c66affSColin Finck * with the same name already exist, internal Atom counter is incremented.
67c2c66affSColin Finck * See: http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Atoms/NtAddAtom.html
68c2c66affSColin Finck *
69c2c66affSColin Finck * @param AtomName
70c2c66affSColin Finck * Atom name in Unicode
71c2c66affSColin Finck *
72c2c66affSColin Finck * @param AtomNameLength
73c2c66affSColin Finck * Length of the atom name
74c2c66affSColin Finck *
75c2c66affSColin Finck * @param Atom
76c2c66affSColin Finck * Pointer to RTL_ATOM
77c2c66affSColin Finck *
78c2c66affSColin Finck * @return STATUS_SUCCESS in case of success, proper error code
79c2c66affSColin Finck * otherwise.
80c2c66affSColin Finck *
81c2c66affSColin Finck * @remarks None
82c2c66affSColin Finck *
83c2c66affSColin Finck *--*/
84c2c66affSColin Finck NTSTATUS
85c2c66affSColin Finck NTAPI
NtAddAtom(IN PWSTR AtomName,IN ULONG AtomNameLength,OUT PRTL_ATOM Atom)86c2c66affSColin Finck NtAddAtom(IN PWSTR AtomName,
87c2c66affSColin Finck IN ULONG AtomNameLength,
88c2c66affSColin Finck OUT PRTL_ATOM Atom)
89c2c66affSColin Finck {
90c2c66affSColin Finck PRTL_ATOM_TABLE AtomTable = ExpGetGlobalAtomTable();
91c2c66affSColin Finck NTSTATUS Status;
92c2c66affSColin Finck KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
93c2c66affSColin Finck LPWSTR CapturedName;
94c2c66affSColin Finck ULONG CapturedSize;
95c2c66affSColin Finck RTL_ATOM SafeAtom;
96c2c66affSColin Finck PAGED_CODE();
97c2c66affSColin Finck
98c2c66affSColin Finck /* Check for the table */
99c2c66affSColin Finck if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
100c2c66affSColin Finck
101c2c66affSColin Finck /* Check for valid name */
102c2c66affSColin Finck if (AtomNameLength > (RTL_MAXIMUM_ATOM_LENGTH * sizeof(WCHAR)))
103c2c66affSColin Finck {
104c2c66affSColin Finck /* Fail */
105c2c66affSColin Finck DPRINT1("Atom name too long\n");
106c2c66affSColin Finck return STATUS_INVALID_PARAMETER;
107c2c66affSColin Finck }
108c2c66affSColin Finck
109c2c66affSColin Finck /* Check if we're called from user-mode or kernel-mode */
110c2c66affSColin Finck if (PreviousMode == KernelMode)
111c2c66affSColin Finck {
112c2c66affSColin Finck /* Re-use the given name if kernel mode */
113c2c66affSColin Finck CapturedName = AtomName;
114c2c66affSColin Finck }
115c2c66affSColin Finck else
116c2c66affSColin Finck {
117c2c66affSColin Finck /* Check if we have a name */
118c2c66affSColin Finck if (AtomName)
119c2c66affSColin Finck {
120c2c66affSColin Finck /* Allocate an aligned buffer + the null char */
121c2c66affSColin Finck CapturedSize = ((AtomNameLength + sizeof(WCHAR)) &
122c2c66affSColin Finck ~(sizeof(WCHAR) -1));
123c2c66affSColin Finck CapturedName = ExAllocatePoolWithTag(PagedPool,
124c2c66affSColin Finck CapturedSize,
125c2c66affSColin Finck TAG_ATOM);
126c2c66affSColin Finck
127c2c66affSColin Finck if (!CapturedName)
128c2c66affSColin Finck {
129c2c66affSColin Finck /* Fail the call */
130c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
131c2c66affSColin Finck }
132c2c66affSColin Finck
133c2c66affSColin Finck /* Enter SEH */
134c2c66affSColin Finck _SEH2_TRY
135c2c66affSColin Finck {
136c2c66affSColin Finck /* Probe the atom */
137c2c66affSColin Finck ProbeForRead(AtomName, AtomNameLength, sizeof(WCHAR));
138c2c66affSColin Finck
139c2c66affSColin Finck /* Copy the name and null-terminate it */
140c2c66affSColin Finck RtlCopyMemory(CapturedName, AtomName, AtomNameLength);
141c2c66affSColin Finck CapturedName[AtomNameLength / sizeof(WCHAR)] = UNICODE_NULL;
142c2c66affSColin Finck
143c2c66affSColin Finck /* Probe the atom too */
144c2c66affSColin Finck if (Atom) ProbeForWriteUshort(Atom);
145c2c66affSColin Finck }
146c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
147c2c66affSColin Finck {
148c2c66affSColin Finck /* Return the exception code */
149c2c66affSColin Finck _SEH2_YIELD(return _SEH2_GetExceptionCode());
150c2c66affSColin Finck }
151c2c66affSColin Finck _SEH2_END;
152c2c66affSColin Finck }
153c2c66affSColin Finck else
154c2c66affSColin Finck {
155c2c66affSColin Finck /* No name */
156c2c66affSColin Finck CapturedName = NULL;
157c2c66affSColin Finck }
158c2c66affSColin Finck }
159c2c66affSColin Finck
160c2c66affSColin Finck /* Call the runtime function */
161c2c66affSColin Finck Status = RtlAddAtomToAtomTable(AtomTable, CapturedName, &SafeAtom);
162c2c66affSColin Finck if (NT_SUCCESS(Status) && (Atom))
163c2c66affSColin Finck {
164c2c66affSColin Finck /* Success and caller wants the atom back.. .enter SEH */
165c2c66affSColin Finck _SEH2_TRY
166c2c66affSColin Finck {
167c2c66affSColin Finck /* Return the atom */
168c2c66affSColin Finck *Atom = SafeAtom;
169c2c66affSColin Finck }
170c2c66affSColin Finck _SEH2_EXCEPT(ExSystemExceptionFilter())
171c2c66affSColin Finck {
172c2c66affSColin Finck /* Get the exception code */
173c2c66affSColin Finck Status = _SEH2_GetExceptionCode();
174c2c66affSColin Finck }
175c2c66affSColin Finck _SEH2_END;
176c2c66affSColin Finck }
177c2c66affSColin Finck
178c2c66affSColin Finck /* If we captured anything, free it */
179c2c66affSColin Finck if ((CapturedName != NULL) && (CapturedName != AtomName))
180c2c66affSColin Finck ExFreePoolWithTag(CapturedName, TAG_ATOM);
181c2c66affSColin Finck
182c2c66affSColin Finck /* Return to caller */
183c2c66affSColin Finck return Status;
184c2c66affSColin Finck }
185c2c66affSColin Finck
186c2c66affSColin Finck /*++
187c2c66affSColin Finck * @name NtDeleteAtom
188c2c66affSColin Finck * @implemented
189c2c66affSColin Finck *
190c2c66affSColin Finck * Removes Atom from Global Atom Table. If Atom's reference counter
191c2c66affSColin Finck * is greater then 1, function decrements this counter, but Atom
192c2c66affSColin Finck * stayed in Global Atom Table.
193c2c66affSColin Finck * See: http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Atoms/NtDeleteAtom.html
194c2c66affSColin Finck *
195c2c66affSColin Finck * @param Atom
196c2c66affSColin Finck * Atom identifier
197c2c66affSColin Finck *
198c2c66affSColin Finck * @return STATUS_SUCCESS in case of success, proper error code
199c2c66affSColin Finck * otherwise.
200c2c66affSColin Finck *
201c2c66affSColin Finck * @remarks None
202c2c66affSColin Finck *
203c2c66affSColin Finck *--*/
204c2c66affSColin Finck NTSTATUS
205c2c66affSColin Finck NTAPI
NtDeleteAtom(IN RTL_ATOM Atom)206c2c66affSColin Finck NtDeleteAtom(IN RTL_ATOM Atom)
207c2c66affSColin Finck {
208c2c66affSColin Finck PRTL_ATOM_TABLE AtomTable = ExpGetGlobalAtomTable();
209c2c66affSColin Finck PAGED_CODE();
210c2c66affSColin Finck
211c2c66affSColin Finck /* Check for valid table */
212c2c66affSColin Finck if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
213c2c66affSColin Finck
214c2c66affSColin Finck /* Call worker function */
215c2c66affSColin Finck return RtlDeleteAtomFromAtomTable(AtomTable, Atom);
216c2c66affSColin Finck }
217c2c66affSColin Finck
218c2c66affSColin Finck /*++
219c2c66affSColin Finck * @name NtFindAtom
220c2c66affSColin Finck * @implemented
221c2c66affSColin Finck *
222c2c66affSColin Finck * Retrieves existing Atom's identifier without incrementing Atom's
223c2c66affSColin Finck * internal counter
224c2c66affSColin Finck * See: http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Atoms/NtFindAtom.html
225c2c66affSColin Finck *
226c2c66affSColin Finck * @param AtomName
227c2c66affSColin Finck * Atom name in Unicode
228c2c66affSColin Finck *
229c2c66affSColin Finck * @param AtomNameLength
230c2c66affSColin Finck * Length of the atom name
231c2c66affSColin Finck *
232c2c66affSColin Finck * @param Atom
233c2c66affSColin Finck * Pointer to RTL_ATOM
234c2c66affSColin Finck *
235c2c66affSColin Finck * @return STATUS_SUCCESS in case of success, proper error code
236c2c66affSColin Finck * otherwise.
237c2c66affSColin Finck *
238c2c66affSColin Finck * @remarks None
239c2c66affSColin Finck *
240c2c66affSColin Finck *--*/
241c2c66affSColin Finck NTSTATUS
242c2c66affSColin Finck NTAPI
NtFindAtom(IN PWSTR AtomName,IN ULONG AtomNameLength,OUT PRTL_ATOM Atom)243c2c66affSColin Finck NtFindAtom(IN PWSTR AtomName,
244c2c66affSColin Finck IN ULONG AtomNameLength,
245c2c66affSColin Finck OUT PRTL_ATOM Atom)
246c2c66affSColin Finck {
247c2c66affSColin Finck PRTL_ATOM_TABLE AtomTable = ExpGetGlobalAtomTable();
248c2c66affSColin Finck NTSTATUS Status;
249c2c66affSColin Finck KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
250*aa9a0981SThomas Faber _SEH2_VOLATILE LPWSTR CapturedName;
251c2c66affSColin Finck ULONG CapturedSize;
252c2c66affSColin Finck RTL_ATOM SafeAtom;
253c2c66affSColin Finck PAGED_CODE();
254c2c66affSColin Finck
255c2c66affSColin Finck /* Check for the table */
256c2c66affSColin Finck if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
257c2c66affSColin Finck
258c2c66affSColin Finck /* Check for valid name */
259c2c66affSColin Finck if (AtomNameLength > (RTL_MAXIMUM_ATOM_LENGTH * sizeof(WCHAR)))
260c2c66affSColin Finck {
261c2c66affSColin Finck /* Fail */
262c2c66affSColin Finck DPRINT1("Atom name too long\n");
263c2c66affSColin Finck return STATUS_INVALID_PARAMETER;
264c2c66affSColin Finck }
265c2c66affSColin Finck
266c2c66affSColin Finck /* Re-use the given name if kernel mode or no atom name */
267c2c66affSColin Finck CapturedName = AtomName;
268c2c66affSColin Finck
269c2c66affSColin Finck /* Check if we're called from user-mode*/
270c2c66affSColin Finck if (PreviousMode != KernelMode)
271c2c66affSColin Finck {
272c2c66affSColin Finck /* Enter SEH */
273c2c66affSColin Finck _SEH2_TRY
274c2c66affSColin Finck {
275c2c66affSColin Finck /* Check if we have a name */
276c2c66affSColin Finck if (AtomName)
277c2c66affSColin Finck {
278c2c66affSColin Finck /* Probe the atom */
279c2c66affSColin Finck ProbeForRead(AtomName, AtomNameLength, sizeof(WCHAR));
280c2c66affSColin Finck
281c2c66affSColin Finck /* Allocate an aligned buffer + the null char */
282c2c66affSColin Finck CapturedSize = ((AtomNameLength + sizeof(WCHAR)) &~
283c2c66affSColin Finck (sizeof(WCHAR) -1));
284*aa9a0981SThomas Faber CapturedName = ExAllocatePoolWithQuotaTag(PagedPool,
285c2c66affSColin Finck CapturedSize,
286c2c66affSColin Finck TAG_ATOM);
287c2c66affSColin Finck /* Copy the name and null-terminate it */
288c2c66affSColin Finck RtlCopyMemory(CapturedName, AtomName, AtomNameLength);
289c2c66affSColin Finck CapturedName[AtomNameLength / sizeof(WCHAR)] = UNICODE_NULL;
290c2c66affSColin Finck
291c2c66affSColin Finck /* Probe the atom too */
292c2c66affSColin Finck if (Atom) ProbeForWriteUshort(Atom);
293c2c66affSColin Finck }
294c2c66affSColin Finck }
295c2c66affSColin Finck _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
296c2c66affSColin Finck {
297*aa9a0981SThomas Faber if (CapturedName != AtomName)
298*aa9a0981SThomas Faber {
299*aa9a0981SThomas Faber ExFreePoolWithTag(CapturedName, TAG_ATOM);
300*aa9a0981SThomas Faber }
301*aa9a0981SThomas Faber
302c2c66affSColin Finck /* Return the exception code */
303c2c66affSColin Finck _SEH2_YIELD(return _SEH2_GetExceptionCode());
304c2c66affSColin Finck }
305c2c66affSColin Finck _SEH2_END;
306c2c66affSColin Finck }
307c2c66affSColin Finck
308c2c66affSColin Finck /* Call the runtime function */
309c2c66affSColin Finck Status = RtlLookupAtomInAtomTable(AtomTable, CapturedName, &SafeAtom);
310c2c66affSColin Finck if (NT_SUCCESS(Status) && (Atom))
311c2c66affSColin Finck {
312c2c66affSColin Finck /* Success and caller wants the atom back... enter SEH */
313c2c66affSColin Finck _SEH2_TRY
314c2c66affSColin Finck {
315c2c66affSColin Finck /* Return the atom */
316c2c66affSColin Finck *Atom = SafeAtom;
317c2c66affSColin Finck }
318c2c66affSColin Finck _SEH2_EXCEPT(ExSystemExceptionFilter())
319c2c66affSColin Finck {
320c2c66affSColin Finck Status = _SEH2_GetExceptionCode();
321c2c66affSColin Finck }
322c2c66affSColin Finck _SEH2_END;
323c2c66affSColin Finck }
324c2c66affSColin Finck
325c2c66affSColin Finck /* If we captured anything, free it */
326c2c66affSColin Finck if ((CapturedName) && (CapturedName != AtomName))
327c2c66affSColin Finck ExFreePoolWithTag(CapturedName, TAG_ATOM);
328c2c66affSColin Finck
329c2c66affSColin Finck /* Return to caller */
330c2c66affSColin Finck return Status;
331c2c66affSColin Finck }
332c2c66affSColin Finck
333c2c66affSColin Finck /*++
334c2c66affSColin Finck * @name NtQueryInformationAtom
335c2c66affSColin Finck * @implemented
336c2c66affSColin Finck *
337c2c66affSColin Finck * Gets single Atom properties or reads Global Atom Table
338c2c66affSColin Finck * See: http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/Atoms/NtQueryInformationAtom.html
339c2c66affSColin Finck *
340c2c66affSColin Finck * @param Atom
341c2c66affSColin Finck * Atom to query. If AtomInformationClass parameter is
342c2c66affSColin Finck * AtomTableInformation, Atom parameter is not used.
343c2c66affSColin Finck *
344c2c66affSColin Finck * @param AtomInformationClass
345c2c66affSColin Finck * See ATOM_INFORMATION_CLASS enumeration type for details
346c2c66affSColin Finck *
347c2c66affSColin Finck * @param AtomInformation
348c2c66affSColin Finck * Result of call - pointer to user's allocated buffer for data
349c2c66affSColin Finck *
350c2c66affSColin Finck * @param AtomInformationLength
351c2c66affSColin Finck * Size of AtomInformation buffer, in bytes
352c2c66affSColin Finck *
353c2c66affSColin Finck * @param ReturnLength
354c2c66affSColin Finck * Pointer to ULONG value containing required AtomInformation
355c2c66affSColin Finck * buffer size
356c2c66affSColin Finck *
357c2c66affSColin Finck * @return STATUS_SUCCESS in case of success, proper error code
358c2c66affSColin Finck * otherwise.
359c2c66affSColin Finck *
360c2c66affSColin Finck * @remarks None
361c2c66affSColin Finck *
362c2c66affSColin Finck *--*/
363c2c66affSColin Finck NTSTATUS
364c2c66affSColin Finck NTAPI
NtQueryInformationAtom(RTL_ATOM Atom,ATOM_INFORMATION_CLASS AtomInformationClass,PVOID AtomInformation,ULONG AtomInformationLength,PULONG ReturnLength)365c2c66affSColin Finck NtQueryInformationAtom(RTL_ATOM Atom,
366c2c66affSColin Finck ATOM_INFORMATION_CLASS AtomInformationClass,
367c2c66affSColin Finck PVOID AtomInformation,
368c2c66affSColin Finck ULONG AtomInformationLength,
369c2c66affSColin Finck PULONG ReturnLength)
370c2c66affSColin Finck {
371c2c66affSColin Finck PRTL_ATOM_TABLE AtomTable = ExpGetGlobalAtomTable();
372c2c66affSColin Finck PATOM_BASIC_INFORMATION BasicInformation = AtomInformation;
373c2c66affSColin Finck PATOM_TABLE_INFORMATION TableInformation = AtomInformation;
374c2c66affSColin Finck NTSTATUS Status = STATUS_SUCCESS;
375c2c66affSColin Finck ULONG Flags, UsageCount, NameLength, RequiredLength = 0;
376c2c66affSColin Finck KPROCESSOR_MODE PreviousMode;
377c2c66affSColin Finck
378c2c66affSColin Finck PAGED_CODE();
379c2c66affSColin Finck
380c2c66affSColin Finck /* Check for valid table */
381c2c66affSColin Finck if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
382c2c66affSColin Finck
383c2c66affSColin Finck PreviousMode = ExGetPreviousMode();
384c2c66affSColin Finck
385c2c66affSColin Finck _SEH2_TRY
386c2c66affSColin Finck {
387c2c66affSColin Finck /* Probe the parameters */
388c2c66affSColin Finck if (PreviousMode != KernelMode)
389c2c66affSColin Finck {
390c2c66affSColin Finck ProbeForWrite(AtomInformation,
391c2c66affSColin Finck AtomInformationLength,
392c2c66affSColin Finck sizeof(ULONG));
393c2c66affSColin Finck
394c2c66affSColin Finck if (ReturnLength != NULL)
395c2c66affSColin Finck {
396c2c66affSColin Finck ProbeForWriteUlong(ReturnLength);
397c2c66affSColin Finck }
398c2c66affSColin Finck }
399c2c66affSColin Finck
400c2c66affSColin Finck /* Choose class */
401c2c66affSColin Finck switch (AtomInformationClass)
402c2c66affSColin Finck {
403c2c66affSColin Finck /* Caller requested info about an atom */
404c2c66affSColin Finck case AtomBasicInformation:
405c2c66affSColin Finck
406c2c66affSColin Finck /* Size check */
407c2c66affSColin Finck RequiredLength = FIELD_OFFSET(ATOM_BASIC_INFORMATION, Name);
408c2c66affSColin Finck if (RequiredLength > AtomInformationLength)
409c2c66affSColin Finck {
410c2c66affSColin Finck /* Fail */
411c2c66affSColin Finck DPRINT1("Buffer too small\n");
412c2c66affSColin Finck Status = STATUS_INFO_LENGTH_MISMATCH;
413c2c66affSColin Finck _SEH2_LEAVE;
414c2c66affSColin Finck }
415c2c66affSColin Finck
416c2c66affSColin Finck /* Prepare query */
417c2c66affSColin Finck UsageCount = 0;
418c2c66affSColin Finck NameLength = AtomInformationLength - RequiredLength;
419c2c66affSColin Finck BasicInformation->Name[0] = UNICODE_NULL;
420c2c66affSColin Finck
421c2c66affSColin Finck /* Query the data */
422c2c66affSColin Finck Status = RtlQueryAtomInAtomTable(AtomTable,
423c2c66affSColin Finck Atom,
424c2c66affSColin Finck &UsageCount,
425c2c66affSColin Finck &Flags,
426c2c66affSColin Finck BasicInformation->Name,
427c2c66affSColin Finck &NameLength);
428c2c66affSColin Finck if (NT_SUCCESS(Status))
429c2c66affSColin Finck {
430c2c66affSColin Finck /* Return data */
431c2c66affSColin Finck BasicInformation->UsageCount = (USHORT)UsageCount;
432c2c66affSColin Finck BasicInformation->Flags = (USHORT)Flags;
433c2c66affSColin Finck BasicInformation->NameLength = (USHORT)NameLength;
434c2c66affSColin Finck RequiredLength += NameLength + sizeof(WCHAR);
435c2c66affSColin Finck }
436c2c66affSColin Finck break;
437c2c66affSColin Finck
438c2c66affSColin Finck /* Caller requested info about an Atom Table */
439c2c66affSColin Finck case AtomTableInformation:
440c2c66affSColin Finck
441c2c66affSColin Finck /* Size check */
442c2c66affSColin Finck RequiredLength = FIELD_OFFSET(ATOM_TABLE_INFORMATION, Atoms);
443c2c66affSColin Finck if (RequiredLength > AtomInformationLength)
444c2c66affSColin Finck {
445c2c66affSColin Finck /* Fail */
446c2c66affSColin Finck DPRINT1("Buffer too small\n");
447c2c66affSColin Finck Status = STATUS_INFO_LENGTH_MISMATCH;
448c2c66affSColin Finck _SEH2_LEAVE;
449c2c66affSColin Finck }
450c2c66affSColin Finck
451c2c66affSColin Finck /* Query the data */
452c2c66affSColin Finck Status = RtlQueryAtomListInAtomTable(AtomTable,
453c2c66affSColin Finck (AtomInformationLength - RequiredLength) /
454c2c66affSColin Finck sizeof(RTL_ATOM),
455c2c66affSColin Finck &TableInformation->NumberOfAtoms,
456c2c66affSColin Finck TableInformation->Atoms);
457c2c66affSColin Finck if (NT_SUCCESS(Status))
458c2c66affSColin Finck {
459c2c66affSColin Finck /* Update the return length */
460c2c66affSColin Finck RequiredLength += TableInformation->NumberOfAtoms * sizeof(RTL_ATOM);
461c2c66affSColin Finck }
462c2c66affSColin Finck break;
463c2c66affSColin Finck
464c2c66affSColin Finck /* Caller was on crack */
465c2c66affSColin Finck default:
466c2c66affSColin Finck
467c2c66affSColin Finck /* Unrecognized class */
468c2c66affSColin Finck Status = STATUS_INVALID_INFO_CLASS;
469c2c66affSColin Finck break;
470c2c66affSColin Finck }
471c2c66affSColin Finck
472c2c66affSColin Finck /* Return the required size */
473c2c66affSColin Finck if (ReturnLength != NULL)
474c2c66affSColin Finck {
475c2c66affSColin Finck *ReturnLength = RequiredLength;
476c2c66affSColin Finck }
477c2c66affSColin Finck }
478c2c66affSColin Finck _SEH2_EXCEPT(ExSystemExceptionFilter())
479c2c66affSColin Finck {
480c2c66affSColin Finck Status = _SEH2_GetExceptionCode();
481c2c66affSColin Finck }
482c2c66affSColin Finck _SEH2_END;
483c2c66affSColin Finck
484c2c66affSColin Finck /* Return to caller */
485c2c66affSColin Finck return Status;
486c2c66affSColin Finck }
487c2c66affSColin Finck
488c2c66affSColin Finck /* EOF */
489