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