be573da2263387006354e19caf34938e770e4046
[reactos.git] / reactos / ntoskrnl / ex / atom.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ex/atom.c
5 * PURPOSE: Executive Atom Functions
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * Gunnar Dalsnes
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <internal/debug.h>
15
16 /* GLOBALS ****************************************************************/
17
18 /*
19 * FIXME: this is WRONG! The global atom table should live in the WinSta struct
20 * and accessed through a win32k callout (received in PsEstablishWin32Callouts)
21 * NOTE: There is a session/win32k global atom table also, but its private to
22 * win32k. Its used for RegisterWindowMessage() and for window classes.
23 * -Gunnar
24 */
25 PRTL_ATOM_TABLE GlobalAtomTable;
26
27 /* PRIVATE FUNCTIONS *********************************************************/
28
29 PRTL_ATOM_TABLE
30 NTAPI
31 ExpGetGlobalAtomTable(VOID)
32 {
33 NTSTATUS Status;
34
35 /* Return it if we have one */
36 if (GlobalAtomTable) return GlobalAtomTable;
37
38 /* Create it */
39 Status = RtlCreateAtomTable(37, &GlobalAtomTable);
40
41 /* If we couldn't create it, return NULL */
42 if (!NT_SUCCESS(Status)) return NULL;
43
44 /* Return the newly created one */
45 return GlobalAtomTable;
46 }
47
48 NTSTATUS
49 NTAPI
50 RtlpQueryAtomInformation(PRTL_ATOM_TABLE AtomTable,
51 RTL_ATOM Atom,
52 PATOM_BASIC_INFORMATION AtomInformation,
53 ULONG AtomInformationLength,
54 PULONG ReturnLength)
55 {
56 NTSTATUS Status;
57 ULONG UsageCount;
58 ULONG Flags;
59 ULONG NameLength;
60
61 NameLength = AtomInformationLength - sizeof(ATOM_BASIC_INFORMATION) + sizeof(WCHAR);
62 Status = RtlQueryAtomInAtomTable(AtomTable,
63 Atom,
64 &UsageCount,
65 &Flags,
66 AtomInformation->Name,
67 &NameLength);
68
69 if (!NT_SUCCESS(Status)) return Status;
70 DPRINT("NameLength: %lu\n", NameLength);
71
72 if (ReturnLength != NULL)
73 {
74 *ReturnLength = NameLength + sizeof(ATOM_BASIC_INFORMATION);
75 }
76
77 if (NameLength + sizeof(ATOM_BASIC_INFORMATION) > AtomInformationLength)
78 {
79 return STATUS_INFO_LENGTH_MISMATCH;
80 }
81
82 AtomInformation->UsageCount = (USHORT)UsageCount;
83 AtomInformation->Flags = (USHORT)Flags;
84 AtomInformation->NameLength = (USHORT)NameLength;
85
86 return STATUS_SUCCESS;
87 }
88
89 NTSTATUS
90 NTAPI
91 RtlpQueryAtomTableInformation(PRTL_ATOM_TABLE AtomTable,
92 RTL_ATOM Atom,
93 PATOM_TABLE_INFORMATION AtomInformation,
94 ULONG AtomInformationLength,
95 PULONG ReturnLength)
96 {
97 ULONG Length;
98 NTSTATUS Status;
99
100 Length = sizeof(ATOM_TABLE_INFORMATION);
101 DPRINT("RequiredLength: %lu\n", Length);
102
103 if (ReturnLength) *ReturnLength = Length;
104
105 if (Length > AtomInformationLength) return STATUS_INFO_LENGTH_MISMATCH;
106
107 Status = RtlQueryAtomListInAtomTable(AtomTable,
108 (AtomInformationLength - Length) /
109 sizeof(RTL_ATOM),
110 &AtomInformation->NumberOfAtoms,
111 AtomInformation->Atoms);
112 if (NT_SUCCESS(Status))
113 {
114 ReturnLength += AtomInformation->NumberOfAtoms * sizeof(RTL_ATOM);
115 if (ReturnLength != NULL) *ReturnLength = Length;
116 }
117
118 return Status;
119 }
120
121 /* FUNCTIONS ****************************************************************/
122
123 /*
124 * @implemented
125 */
126 NTSTATUS
127 NTAPI
128 NtAddAtom(IN PWSTR AtomName,
129 IN ULONG AtomNameLength,
130 OUT PRTL_ATOM Atom)
131 {
132 PRTL_ATOM_TABLE AtomTable = ExpGetGlobalAtomTable();
133
134 /* Check for the table */
135 if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
136
137 /* FIXME: SEH! */
138
139 /* Call the worker function */
140 return RtlAddAtomToAtomTable(AtomTable, AtomName, Atom);
141 }
142
143 /*
144 * @implemented
145 */
146 NTSTATUS
147 NTAPI
148 NtDeleteAtom(IN RTL_ATOM Atom)
149 {
150 PRTL_ATOM_TABLE AtomTable = ExpGetGlobalAtomTable();
151
152 /* Check for valid table */
153 if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
154
155 /* Call worker function */
156 return RtlDeleteAtomFromAtomTable(AtomTable, Atom);
157 }
158
159 /*
160 * @implemented
161 */
162 NTSTATUS
163 NTAPI
164 NtFindAtom(IN PWSTR AtomName,
165 IN ULONG AtomNameLength,
166 OUT PRTL_ATOM Atom)
167 {
168 PRTL_ATOM_TABLE AtomTable = ExpGetGlobalAtomTable();
169
170 /* Check for valid table */
171 if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
172
173 /* FIXME: SEH!!! */
174
175 /* Call worker function */
176 return RtlLookupAtomInAtomTable(AtomTable, AtomName, Atom);
177 }
178
179 /*
180 * @implemented
181 */
182 NTSTATUS
183 NTAPI
184 NtQueryInformationAtom(RTL_ATOM Atom,
185 ATOM_INFORMATION_CLASS AtomInformationClass,
186 PVOID AtomInformation,
187 ULONG AtomInformationLength,
188 PULONG ReturnLength)
189 {
190 PRTL_ATOM_TABLE AtomTable = ExpGetGlobalAtomTable();
191 NTSTATUS Status;
192
193 /* Check for valid table */
194 if (AtomTable == NULL) return STATUS_ACCESS_DENIED;
195
196 /* FIXME: SEH! */
197
198 /* Choose class */
199 switch (AtomInformationClass)
200 {
201 case AtomBasicInformation:
202 Status = RtlpQueryAtomInformation(AtomTable,
203 Atom,
204 AtomInformation,
205 AtomInformationLength,
206 ReturnLength);
207 break;
208
209 case AtomTableInformation:
210 Status = RtlpQueryAtomTableInformation(AtomTable,
211 Atom,
212 AtomInformation,
213 AtomInformationLength,
214 ReturnLength);
215 break;
216
217 default:
218 Status = STATUS_INVALID_INFO_CLASS;
219 }
220
221 /* Return to caller */
222 return Status;
223 }
224
225 /* EOF */