ReactOS 0.4.17-dev-116-ga4b6fe9
atom.c
Go to the documentation of this file.
1/* Unit test suite for Ntdll atom API functions
2 *
3 * Copyright 2003 Gyorgy 'Nog' Jeney
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 *
19 * NOTES
20 * We use function pointers here as there is no import library for NTDLL on
21 * windows.
22 */
23
24#include <stdio.h>
25#include <stdarg.h>
26
27#include "ntstatus.h"
28/* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro
29 * definition errors when we get to winnt.h
30 */
31#define WIN32_NO_STATUS
32
33#include "windef.h"
34#include "winbase.h"
35#include "winreg.h"
36#include "winnls.h"
37#include "winuser.h"
38#include "wine/test.h"
39#include "winternl.h"
40
41#ifndef __WINE_WINTERNL_H
42typedef unsigned short RTL_ATOM, *PRTL_ATOM;
43typedef struct atom_table *RTL_ATOM_TABLE, **PRTL_ATOM_TABLE;
44#endif
45
46/* Function pointers for ntdll calls */
47static HMODULE hntdll = 0;
48static NTSTATUS (WINAPI *pRtlCreateAtomTable)(ULONG,PRTL_ATOM_TABLE);
49static NTSTATUS (WINAPI *pRtlDestroyAtomTable)(RTL_ATOM_TABLE);
50static NTSTATUS (WINAPI *pRtlEmptyAtomTable)(RTL_ATOM_TABLE,BOOLEAN);
51static NTSTATUS (WINAPI *pRtlAddAtomToAtomTable)(RTL_ATOM_TABLE,PCWSTR,PRTL_ATOM);
52static NTSTATUS (WINAPI *pRtlDeleteAtomFromAtomTable)(RTL_ATOM_TABLE,RTL_ATOM);
53static NTSTATUS (WINAPI *pRtlLookupAtomInAtomTable)(RTL_ATOM_TABLE,PCWSTR,PRTL_ATOM);
54static NTSTATUS (WINAPI *pRtlPinAtomInAtomTable)(RTL_ATOM_TABLE,RTL_ATOM);
55static NTSTATUS (WINAPI *pRtlQueryAtomInAtomTable)(RTL_ATOM_TABLE,RTL_ATOM,PULONG,PULONG,PWSTR,PULONG);
56
57static NTSTATUS (WINAPI* pNtAddAtom)(LPCWSTR,ULONG,RTL_ATOM*);
58static NTSTATUS (WINAPI* pNtAddAtomNT4)(LPCWSTR,RTL_ATOM*);
59static NTSTATUS (WINAPI* pNtQueryInformationAtom)(RTL_ATOM,DWORD,void*,ULONG,PULONG);
60
61static const WCHAR EmptyAtom[] = {0};
62static const WCHAR testAtom1[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
63static const WCHAR testAtom2[] = {'H','e','l','l','o',' ','W','o','r','l','d','2',0};
64static const WCHAR testAtom3[] = {'H','e','l','l','o',' ','W','o','r','l','d','3',0};
65
66static const WCHAR testAtom1Cap[] = {'H','E','L','L','O',' ','W','O','R','L','D',0};
67static const WCHAR testAtom1Low[] = {'h','e','l','l','o',' ','w','o','r','l','d',0};
68
69static const WCHAR testAtomInt[] = {'#','1','3','2',0};
70static const WCHAR testAtomIntInv[] = {'#','2','3','4','z',0};
71static const WCHAR testAtomOTT[] = {'#','1','2','3',0};
72
73static void InitFunctionPtr(void)
74{
75 hntdll = LoadLibraryA("ntdll.dll");
76 ok(hntdll != 0, "Unable to load ntdll.dll\n");
77
78 if (hntdll)
79 {
80 pRtlCreateAtomTable = (void *)GetProcAddress(hntdll, "RtlCreateAtomTable");
81 pRtlDestroyAtomTable = (void *)GetProcAddress(hntdll, "RtlDestroyAtomTable");
82 pRtlEmptyAtomTable = (void *)GetProcAddress(hntdll, "RtlEmptyAtomTable");
83 pRtlAddAtomToAtomTable = (void *)GetProcAddress(hntdll, "RtlAddAtomToAtomTable");
84 pRtlDeleteAtomFromAtomTable = (void *)GetProcAddress(hntdll, "RtlDeleteAtomFromAtomTable");
85 pRtlLookupAtomInAtomTable = (void *)GetProcAddress(hntdll, "RtlLookupAtomInAtomTable");
86 pRtlPinAtomInAtomTable = (void *)GetProcAddress(hntdll, "RtlPinAtomInAtomTable");
87 pRtlQueryAtomInAtomTable = (void *)GetProcAddress(hntdll, "RtlQueryAtomInAtomTable");
88
89 pNtAddAtom = (void *)GetProcAddress(hntdll, "NtAddAtom");
90 pNtQueryInformationAtom = (void *)GetProcAddress(hntdll, "NtQueryInformationAtom");
91 }
92}
93
95{
99 ULONG RefCount = 0, PinCount = 0, Len = 0;
100 WCHAR Name[64];
101
102 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &Atom);
103 ok(!res, "Unable to find atom from another thread, retval: %lx\n", res);
104
105 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &Atom);
106 ok(!res, "Unable to lookup pinned atom in table, retval: %lx\n", res);
107
108 res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, Name, &Len);
109 ok(res == STATUS_BUFFER_TOO_SMALL, "We got wrong retval: %lx\n", res);
110
111 Len = 64;
112 res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, Name, &Len);
113 ok(!res, "Failed with long enough buffer, retval: %lx\n", res);
114 ok(RefCount == 1, "Refcount was not 1 but %lx\n", RefCount);
115 ok(PinCount == 1, "Pincount was not 1 but %lx\n", PinCount);
116 ok(!lstrcmpW(Name, testAtom2), "We found wrong atom!!\n");
117 ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
118
119 Len = 64;
120 res = pRtlQueryAtomInAtomTable(AtomTable, Atom, NULL, NULL, Name, &Len);
121 ok(!res, "RtlQueryAtomInAtomTable with optional args invalid failed, retval: %lx\n", res);
122 ok(!lstrcmpW(Name, testAtom2), "Found Wrong atom!\n");
123 ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
124
125 res = pRtlPinAtomInAtomTable(AtomTable, Atom);
126 ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);
127
128 return 0;
129}
130
131static void test_NtAtom(void)
132{
133 RTL_ATOM_TABLE AtomTable = NULL;
135 RTL_ATOM Atom1, Atom2, Atom3, testEAtom, testAtom;
136 HANDLE testThread;
137 ULONG RefCount = 0, PinCount = 0, Len = 0;
138 WCHAR Name[64];
139
140 /* If we pass a non-null string to create atom table, then it thinks that we
141 * have passed it an already allocated atom table */
142 res = pRtlCreateAtomTable(0, &AtomTable);
143 ok(!res, "RtlCreateAtomTable should succeed with an atom table size of 0\n");
144
145 if (!res)
146 {
147 res = pRtlDestroyAtomTable(AtomTable);
148 ok(!res, "We could create the atom table, but we couldn't destroy it! retval: %lx\n", res);
149 }
150
151 AtomTable = NULL;
152 res = pRtlCreateAtomTable(37, &AtomTable);
153 ok(!res, "We're unable to create an atom table with a valid table size retval: %lx\n", res);
154 if (!res)
155 {
156 ok( *(DWORD *)AtomTable == 0x6d6f7441, "wrong signature %lx\n", *(DWORD *)AtomTable );
157
158 res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1);
159 ok(!res, "We were unable to add a simple atom to the atom table, retval: %lx\n", res);
160
161 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1Cap, &testAtom);
162 ok(!res, "We were unable to find capital version of the atom, retval: %lx\n", res);
163 ok(Atom1 == testAtom, "Found wrong atom in table when querying capital atom\n");
164
165 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1Low, &testAtom);
166 ok(!res, "Unable to find lowercase version of the atom, retval: %lx\n", res);
167 ok(testAtom == Atom1, "Found wrong atom when querying lowercase atom\n");
168
169 res = pRtlAddAtomToAtomTable(AtomTable, EmptyAtom, &testEAtom);
170 ok(res == STATUS_OBJECT_NAME_INVALID, "Got wrong retval, retval: %lx\n", res);
171
172 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
173 ok(!res, "Failed to find totally legitimate atom, retval: %lx\n", res);
174 ok(testAtom == Atom1, "Found wrong atom!\n");
175
176 res = pRtlAddAtomToAtomTable(AtomTable, testAtom2, &Atom2);
177 ok(!res, "Unable to add other legitimate atom to table, retval: %lx\n", res);
178
179 res = pRtlPinAtomInAtomTable(AtomTable, Atom2);
180 ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);
181
182 testThread = CreateThread(NULL, 0, RtlAtomTestThread, &AtomTable, 0, NULL);
183 WaitForSingleObject(testThread, INFINITE);
184 CloseHandle(testThread);
185
186 Len = 64;
187 res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, &RefCount, &PinCount, Name, &Len);
188 ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);
189 ok(RefCount == 1, "RefCount is not 1 but %lx\n", RefCount);
190 ok(PinCount == 1, "PinCount is not 1 but %lx\n", PinCount);
191 ok(!lstrcmpW(Name, testAtom2), "We found wrong atom\n");
192 ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
193
194 res = pRtlEmptyAtomTable(AtomTable, FALSE);
195 ok(!res, "Unable to empty atom table, retval %lx\n", res);
196
197 Len = 64;
198 res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, &RefCount, &PinCount, Name, &Len);
199 ok(!res, "It seems RtlEmptyAtomTable deleted our pinned atom eaven though we asked it not to, retval: %lx\n", res);
200 ok(RefCount == 1, "RefCount is not 1 but %lx\n", RefCount);
201 ok(PinCount == 1, "PinCount is not 1 but %lx\n", PinCount);
202 ok(!lstrcmpW(Name, testAtom2), "We found wrong atom\n");
203 ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
204
205 Len = 8;
206 Name[0] = Name[1] = Name[2] = Name[3] = Name[4] = 0x1337;
207 res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, NULL, NULL, Name, &Len);
208 ok(!res, "query atom %lx\n", res);
209 ok(Len == 6, "wrong length %lu\n", Len);
210 ok(!memcmp(Name, testAtom2, Len), "wrong atom string\n");
211 ok(!Name[3], "wrong string termination\n");
212 ok(Name[4] == 0x1337, "buffer overwrite\n");
213
214 Len = lstrlenW(testAtom2) * sizeof(WCHAR);
215 memset(Name, '.', sizeof(Name));
216 res = pRtlQueryAtomInAtomTable( AtomTable, Atom2, NULL, NULL, Name, &Len );
217 ok(!res, "query atom %lx\n", res);
218 ok(Len == (lstrlenW(testAtom2) - 1) * sizeof(WCHAR), "wrong length %lu\n", Len);
219 ok(!memcmp(testAtom2, Name, (lstrlenW(testAtom2) - 1) * sizeof(WCHAR)), "wrong atom name\n");
220 ok(Name[lstrlenW(testAtom2) - 1] == '\0', "wrong char\n");
221 ok(Name[lstrlenW(testAtom2)] == ('.' << 8) + '.', "wrong char\n");
222
223 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &testAtom);
224 ok(!res, "We can't find our pinned atom!! retval: %lx\n", res);
225 ok(testAtom == Atom2, "We found wrong atom!!!\n");
226
227 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
228 ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "We found the atom in our table eaven though we asked RtlEmptyAtomTable to remove it, retval: %lx\n", res);
229
230 res = pRtlAddAtomToAtomTable(AtomTable, testAtom3, &Atom3);
231 ok(!res, "Unable to add atom to table, retval: %lx\n", res);
232
233 res = pRtlEmptyAtomTable(AtomTable, TRUE);
234 ok(!res, "Unable to empty atom table, retval: %lx\n", res);
235
236 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &testAtom);
237 ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "The pinned atom should be removed, retval: %lx\n", res);
238
239 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom3, &testAtom);
240 ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Non pinned atom should also be removed, retval: %lx\n", res);
241
242 res = pRtlDestroyAtomTable(AtomTable);
243 ok(!res, "Can't destroy atom table, retval: %lx\n", res);
244 }
245
246 AtomTable = NULL;
247 res = pRtlCreateAtomTable(37, &AtomTable);
248 ok(!res, "Unable to create atom table, retval: %lx\n", res);
249
250 if (!res)
251 {
252 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
253 ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Didn't get expected retval with querying an empty atom table, retval: %lx\n", res);
254
255 res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1);
256 ok(!res, "Unable to add atom to atom table, retval %lx\n", res);
257
258 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
259 ok(!res, "Can't find previously added atom in table, retval: %lx\n", res);
260 ok(testAtom == Atom1, "Found wrong atom! retval: %lx\n", res);
261
262 res = pRtlDeleteAtomFromAtomTable(AtomTable, Atom1);
263 ok(!res, "Unable to delete atom from table, retval: %lx\n", res);
264
265 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
266 ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Able to find previously deleted atom in table, retval: %lx\n", res);
267
268 res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1);
269 ok(!res, "Unable to add atom to atom table, retval: %lx\n", res);
270
271 Len = 0;
272 res = pRtlQueryAtomInAtomTable(AtomTable, Atom1, NULL, NULL, Name, &Len);
273 ok(res == STATUS_BUFFER_TOO_SMALL, "Got wrong retval, retval: %lx\n", res);
274 ok((lstrlenW(testAtom1) * sizeof(WCHAR)) == Len || broken(!Len) /* nt4 */, "Got wrong length %lx\n", Len);
275 if (!Len) pNtAddAtomNT4 = (void *)pNtAddAtom;
276
277 res = pRtlPinAtomInAtomTable(AtomTable, Atom1);
278 ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);
279
280 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
281 ok(!res, "Unable to find atom in atom table, retval: %lx\n", res);
282 ok(testAtom == Atom1, "Wrong atom found\n");
283
284 res = pRtlDeleteAtomFromAtomTable(AtomTable, Atom1);
285 ok(res == STATUS_WAS_LOCKED, "Unable to delete atom from table, retval: %lx\n", res);
286
287 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
288 ok(!res, "Able to find deleted atom in table\n");
289
290 res = pRtlDestroyAtomTable(AtomTable);
291 ok(!res, "Unable to destroy atom table\n");
292 }
293}
294
295/* Test Adding integer atoms to atom table */
296static void test_NtIntAtom(void)
297{
299 RTL_ATOM_TABLE AtomTable;
300 RTL_ATOM testAtom;
301 ULONG RefCount = 0, PinCount = 0;
302 INT_PTR i;
303 WCHAR Name[64];
304 ULONG Len;
305
306 AtomTable = NULL;
307 res = pRtlCreateAtomTable(37, &AtomTable);
308 ok(!res, "Unable to create atom table, %lx\n", res);
309
310 if (!res)
311 {
312 /* According to the kernel32 functions, integer atoms are only allowed from
313 * 0x0001 to 0xbfff and not 0xc000 to 0xffff, which is correct */
314 res = pRtlAddAtomToAtomTable(AtomTable, NULL, &testAtom);
315 ok(res == STATUS_INVALID_PARAMETER, "Didn't get expected result from adding 0 int atom, retval: %lx\n", res);
316 for (i = 1; i <= 0xbfff; i++)
317 {
318 res = pRtlAddAtomToAtomTable(AtomTable, (LPWSTR)i, &testAtom);
319 ok(!res, "Unable to add valid integer atom %Ii, retval: %lx\n", i, res);
320 }
321
322 for (i = 1; i <= 0xbfff; i++)
323 {
324 res = pRtlLookupAtomInAtomTable(AtomTable, (LPWSTR)i, &testAtom);
325 ok(!res, "Unable to find int atom %Ii, retval: %lx\n", i, res);
326 if (!res)
327 {
328 res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
329 ok(!res, "Unable to pin int atom %Ii, retval: %lx\n", i, res);
330 }
331 }
332
333 for (i = 0xc000; i <= 0xffff; i++)
334 {
335 res = pRtlAddAtomToAtomTable(AtomTable, (LPWSTR)i, &testAtom);
336 ok(res, "Able to illeageal integer atom %Ii, retval: %lx\n", i, res);
337 }
338
339 res = pRtlDestroyAtomTable(AtomTable);
340 ok(!res, "Unable to destroy atom table, retval: %lx\n", res);
341 }
342
343 AtomTable = NULL;
344 res = pRtlCreateAtomTable(37, &AtomTable);
345 ok(!res, "Unable to create atom table, %lx\n", res);
346 if (!res)
347 {
348 res = pRtlLookupAtomInAtomTable(AtomTable, (PWSTR)123, &testAtom);
349 ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);
350
351 res = pRtlAddAtomToAtomTable(AtomTable, testAtomInt, &testAtom);
352 ok(!res, "Unable to add int atom to table, retval: %lx\n", res);
353
354 res = pRtlAddAtomToAtomTable(AtomTable, testAtomIntInv, &testAtom);
355 ok(!res, "Unable to add int atom to table, retval: %lx\n", res);
356
357 res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)123, &testAtom);
358 ok(!res, "Unable to add int atom to table, retval: %lx\n", res);
359
360 res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)123, &testAtom);
361 ok(!res, "Unable to re-add int atom to table, retval: %lx\n", res);
362
363 Len = 64;
364 res = pRtlQueryAtomInAtomTable(AtomTable, testAtom, &RefCount, &PinCount, Name, &Len);
365 ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);
366 ok(PinCount == 1, "Expected pincount 1 but got %lx\n", PinCount);
367 ok(RefCount == 1, "Expected refcount 1 but got %lx\n", RefCount);
368 ok(!lstrcmpW(testAtomOTT, Name), "Got wrong atom name\n");
369 ok((lstrlenW(testAtomOTT) * sizeof(WCHAR)) == Len, "Got wrong len %ld\n", Len);
370
371 res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
372 ok(!res, "Unable to pin int atom, retval: %lx\n", res);
373
374 res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
375 ok(!res, "Unable to pin int atom, retval: %lx\n", res);
376
377 res = pRtlQueryAtomInAtomTable(AtomTable, testAtom, &RefCount, &PinCount, NULL, NULL);
378 ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);
379 ok(PinCount == 1, "Expected pincount 1 but got %lx\n", PinCount);
380 ok(RefCount == 1, "Expected refcount 1 but got %lx\n", RefCount);
381
382 res = pRtlDestroyAtomTable(AtomTable);
383 ok(!res, "Unable to destroy atom table, retval: %lx\n", res);
384 }
385}
386
387/* Tests to see how the pincount and refcount actually works */
388static void test_NtRefPinAtom(void)
389{
390 RTL_ATOM_TABLE AtomTable;
392 ULONG PinCount = 0, RefCount = 0;
394
395 AtomTable = NULL;
396 res = pRtlCreateAtomTable(37, &AtomTable);
397 ok(!res, "Unable to create atom table, %lx\n", res);
398
399 if (!res)
400 {
401 res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom);
402 ok(!res, "Unable to add our atom to the atom table, retval: %lx\n", res);
403
404 res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom);
405 ok(!res, "Unable to add our atom to the atom table, retval: %lx\n", res);
406
407 res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom);
408 ok(!res, "Unable to add our atom to the atom table, retval: %lx\n", res);
409
410 res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, NULL, NULL);
411 ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);
412 ok(PinCount == 0, "Expected pincount 0 but got %lx\n", PinCount);
413 ok(RefCount == 3, "Expected refcount 3 but got %lx\n", RefCount);
414
415 res = pRtlPinAtomInAtomTable(AtomTable, Atom);
416 ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);
417
418 res = pRtlPinAtomInAtomTable(AtomTable, Atom);
419 ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);
420
421 res = pRtlPinAtomInAtomTable(AtomTable, Atom);
422 ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);
423
424 res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, NULL, NULL);
425 ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);
426 ok(PinCount == 1, "Expected pincount 1 but got %lx\n", PinCount);
427 ok(RefCount == 3, "Expected refcount 3 but got %lx\n", RefCount);
428
429 res = pRtlDestroyAtomTable(AtomTable);
430 ok(!res, "Unable to destroy atom table, retval: %lx\n", res);
431 }
432}
433
434static void test_Global(void)
435{
437 RTL_ATOM atom;
438 ULONG ptr[(sizeof(ATOM_BASIC_INFORMATION) + 255 * sizeof(WCHAR)) / sizeof(ULONG)];
440 ULONG ptr_size = sizeof(ptr);
441
442 if (pNtAddAtomNT4)
443 res = pNtAddAtomNT4(testAtom1, &atom);
444 else
445 res = pNtAddAtom(testAtom1, lstrlenW(testAtom1) * sizeof(WCHAR), &atom);
446
447 ok(!res, "Added atom (%lx)\n", res);
448
449 memset( ptr, 0xcc, sizeof(ptr) );
450 res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
451 ok(!res, "atom lookup\n");
452 ok(!lstrcmpW(abi->Name, testAtom1), "ok strings\n");
453 ok(abi->NameLength == lstrlenW(testAtom1) * sizeof(WCHAR), "wrong string length\n");
454 ok(abi->Name[lstrlenW(testAtom1)] == 0, "wrong string termination %x\n", abi->Name[lstrlenW(testAtom1)]);
455 ok(abi->Name[lstrlenW(testAtom1) + 1] == 0xcccc, "buffer overwrite %x\n", abi->Name[lstrlenW(testAtom1) + 1]);
456
458 res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
459 ok(res == STATUS_BUFFER_TOO_SMALL, "wrong return status (%lx)\n", res);
460 ok(abi->NameLength == lstrlenW(testAtom1) * sizeof(WCHAR) || broken(abi->NameLength == sizeof(WCHAR)), /* nt4 */
461 "string length %u\n",abi->NameLength);
462
463 memset( ptr, 0xcc, sizeof(ptr) );
465 res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
466 ok(!res, "atom lookup %lx\n", res);
467 ok(!lstrcmpW(abi->Name, testAtom1), "strings don't match\n");
468 ok(abi->NameLength == lstrlenW(testAtom1) * sizeof(WCHAR), "wrong string length\n");
469 ok(abi->Name[lstrlenW(testAtom1)] == 0, "buffer overwrite %x\n", abi->Name[lstrlenW(testAtom1)]);
470 ok(abi->Name[lstrlenW(testAtom1) + 1] == 0xcccc, "buffer overwrite %x\n", abi->Name[lstrlenW(testAtom1) + 1]);
471
472 memset( ptr, 0xcc, sizeof(ptr) );
473 ptr_size = sizeof(ATOM_BASIC_INFORMATION) + 4 * sizeof(WCHAR);
474 res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
475 ok(!res, "couldn't find atom\n");
476 ok(abi->NameLength == 8, "wrong string length %u\n", abi->NameLength);
477 ok(!memcmp(abi->Name, testAtom1, 8), "strings don't match\n");
478}
479
481{
483 if (pRtlCreateAtomTable)
484 {
485 /* Global atom table seems to be available to GUI apps only in
486 Win7, so let's turn this app into a GUI app */
488
489 test_NtAtom();
492 test_Global();
493 }
494 else
495 win_skip("Needed atom functions are not available\n");
496
498}
static ATOM Atom3
Definition: SetProp.c:10
static ATOM Atom2
Definition: SetProp.c:10
static ATOM Atom1
Definition: SetProp.c:10
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
_Out_ RTL_ATOM * Atom
Definition: class.h:54
#define Len
Definition: deflate.h:82
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NTSTATUS
Definition: precomp.h:19
#define CloseHandle
Definition: compat.h:739
#define GetProcAddress(x, y)
Definition: compat.h:753
#define FreeLibrary(x)
Definition: compat.h:748
#define lstrlenW
Definition: compat.h:750
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4152
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
#define INFINITE
Definition: serial.h:102
unsigned long DWORD
Definition: ntddk_ex.h:95
ASMGENDATA Table[]
Definition: genincdata.c:61
GLuint res
Definition: glext.h:9613
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define win_skip
Definition: minitest.h:67
static PVOID ptr
Definition: dispmode.c:27
static const DWORD ptr_size
Definition: registry.c:58
static HMODULE hntdll
Definition: atom.c:47
static PCWSTR
Definition: atom.c:51
static DWORD WINAPI RtlAtomTestThread(LPVOID Table)
Definition: atom.c:94
static const WCHAR testAtomOTT[]
Definition: atom.c:71
static PULONG
Definition: atom.c:55
static const WCHAR EmptyAtom[]
Definition: atom.c:61
static void test_NtRefPinAtom(void)
Definition: atom.c:388
static const WCHAR testAtomIntInv[]
Definition: atom.c:70
struct atom_table * RTL_ATOM_TABLE
Definition: atom.c:43
static RTL_ATOM *static RTL_ATOM *static DWORD
Definition: atom.c:59
static void test_NtAtom(void)
Definition: atom.c:131
static const WCHAR testAtom2[]
Definition: atom.c:63
static void test_NtIntAtom(void)
Definition: atom.c:296
static const WCHAR testAtom3[]
Definition: atom.c:64
static const WCHAR testAtom1Cap[]
Definition: atom.c:66
static void test_Global(void)
Definition: atom.c:434
static void InitFunctionPtr(void)
Definition: atom.c:73
static const WCHAR testAtomInt[]
Definition: atom.c:69
static const WCHAR testAtom1[]
Definition: atom.c:62
unsigned short RTL_ATOM
Definition: atom.c:42
unsigned short * PRTL_ATOM
Definition: atom.c:42
static const WCHAR testAtom1Low[]
Definition: atom.c:67
static BOOLEAN
Definition: atom.c:50
struct atom_table ** PRTL_ATOM_TABLE
Definition: atom.c:43
struct _ATOM_BASIC_INFORMATION ATOM_BASIC_INFORMATION
@ AtomBasicInformation
Definition: extypes.h:503
#define STATUS_WAS_LOCKED
Definition: ntstatus.h:214
short WCHAR
Definition: pedump.c:58
#define memset(x, y, z)
Definition: compat.h:39
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_In_ const GUID _In_ ULONG PinCount
Definition: strmini.h:505
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
uint16_t * PWSTR
Definition: typedefs.h:56
int32_t INT_PTR
Definition: typedefs.h:64
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint16_t * LPWSTR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define WINAPI
Definition: msvc.h:6
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628