e8ad049aa9b9b3d661a8d403611607fad7a9bbbc
[reactos.git] / modules / rostests / winetests / ntdll / atom.c
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 "ntdll_test.h"
25
26 #ifndef __WINE_WINTERNL_H
27 typedef unsigned short RTL_ATOM, *PRTL_ATOM;
28 typedef struct atom_table *RTL_ATOM_TABLE, **PRTL_ATOM_TABLE;
29 #endif
30
31 /* Function pointers for ntdll calls */
32 static HMODULE hntdll = 0;
33 static NTSTATUS (WINAPI *pRtlCreateAtomTable)(ULONG,PRTL_ATOM_TABLE);
34 static NTSTATUS (WINAPI *pRtlDestroyAtomTable)(RTL_ATOM_TABLE);
35 static NTSTATUS (WINAPI *pRtlEmptyAtomTable)(RTL_ATOM_TABLE,BOOLEAN);
36 static NTSTATUS (WINAPI *pRtlAddAtomToAtomTable)(RTL_ATOM_TABLE,PCWSTR,PRTL_ATOM);
37 static NTSTATUS (WINAPI *pRtlDeleteAtomFromAtomTable)(RTL_ATOM_TABLE,RTL_ATOM);
38 static NTSTATUS (WINAPI *pRtlLookupAtomInAtomTable)(RTL_ATOM_TABLE,PCWSTR,PRTL_ATOM);
39 static NTSTATUS (WINAPI *pRtlPinAtomInAtomTable)(RTL_ATOM_TABLE,RTL_ATOM);
40 static NTSTATUS (WINAPI *pRtlQueryAtomInAtomTable)(RTL_ATOM_TABLE,RTL_ATOM,PULONG,PULONG,PWSTR,PULONG);
41
42 static NTSTATUS (WINAPI* pNtAddAtom)(LPCWSTR,ULONG,RTL_ATOM*);
43 static NTSTATUS (WINAPI* pNtAddAtomNT4)(LPCWSTR,RTL_ATOM*);
44 static NTSTATUS (WINAPI* pNtQueryInformationAtom)(RTL_ATOM,DWORD,void*,ULONG,PULONG);
45
46 static const WCHAR EmptyAtom[] = {0};
47 static const WCHAR testAtom1[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
48 static const WCHAR testAtom2[] = {'H','e','l','l','o',' ','W','o','r','l','d','2',0};
49 static const WCHAR testAtom3[] = {'H','e','l','l','o',' ','W','o','r','l','d','3',0};
50
51 static const WCHAR testAtom1Cap[] = {'H','E','L','L','O',' ','W','O','R','L','D',0};
52 static const WCHAR testAtom1Low[] = {'h','e','l','l','o',' ','w','o','r','l','d',0};
53
54 static const WCHAR testAtomInt[] = {'#','1','3','2',0};
55 static const WCHAR testAtomIntInv[] = {'#','2','3','4','z',0};
56 static const WCHAR testAtomOTT[] = {'#','1','2','3',0};
57
58 static void InitFunctionPtr(void)
59 {
60 hntdll = LoadLibraryA("ntdll.dll");
61 ok(hntdll != 0, "Unable to load ntdll.dll\n");
62
63 if (hntdll)
64 {
65 pRtlCreateAtomTable = (void *)GetProcAddress(hntdll, "RtlCreateAtomTable");
66 pRtlDestroyAtomTable = (void *)GetProcAddress(hntdll, "RtlDestroyAtomTable");
67 pRtlEmptyAtomTable = (void *)GetProcAddress(hntdll, "RtlEmptyAtomTable");
68 pRtlAddAtomToAtomTable = (void *)GetProcAddress(hntdll, "RtlAddAtomToAtomTable");
69 pRtlDeleteAtomFromAtomTable = (void *)GetProcAddress(hntdll, "RtlDeleteAtomFromAtomTable");
70 pRtlLookupAtomInAtomTable = (void *)GetProcAddress(hntdll, "RtlLookupAtomInAtomTable");
71 pRtlPinAtomInAtomTable = (void *)GetProcAddress(hntdll, "RtlPinAtomInAtomTable");
72 pRtlQueryAtomInAtomTable = (void *)GetProcAddress(hntdll, "RtlQueryAtomInAtomTable");
73
74 pNtAddAtom = (void *)GetProcAddress(hntdll, "NtAddAtom");
75 pNtQueryInformationAtom = (void *)GetProcAddress(hntdll, "NtQueryInformationAtom");
76 }
77 }
78
79 static DWORD WINAPI RtlAtomTestThread(LPVOID Table)
80 {
81 RTL_ATOM_TABLE AtomTable = *(PRTL_ATOM_TABLE)Table;
82 RTL_ATOM Atom;
83 NTSTATUS res;
84 ULONG RefCount = 0, PinCount = 0, Len = 0;
85 WCHAR Name[64];
86
87 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &Atom);
88 ok(!res, "Unable to find atom from another thread, retval: %x\n", res);
89
90 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &Atom);
91 ok(!res, "Unable to lookup pinned atom in table, retval: %x\n", res);
92
93 res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, Name, &Len);
94 ok(res == STATUS_BUFFER_TOO_SMALL, "We got wrong retval: %x\n", res);
95
96 Len = 64;
97 res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, Name, &Len);
98 ok(!res, "Failed with long enough buffer, retval: %x\n", res);
99 ok(RefCount == 1, "Refcount was not 1 but %x\n", RefCount);
100 ok(PinCount == 1, "Pincount was not 1 but %x\n", PinCount);
101 ok(!lstrcmpW(Name, testAtom2), "We found wrong atom!!\n");
102 ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %d\n", Len);
103
104 Len = 64;
105 res = pRtlQueryAtomInAtomTable(AtomTable, Atom, NULL, NULL, Name, &Len);
106 ok(!res, "RtlQueryAtomInAtomTable with optional args invalid failed, retval: %x\n", res);
107 ok(!lstrcmpW(Name, testAtom2), "Found Wrong atom!\n");
108 ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %d\n", Len);
109
110 res = pRtlPinAtomInAtomTable(AtomTable, Atom);
111 ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
112
113 return 0;
114 }
115
116 static void test_NtAtom(void)
117 {
118 RTL_ATOM_TABLE AtomTable = NULL;
119 NTSTATUS res;
120 RTL_ATOM Atom1, Atom2, Atom3, testEAtom, testAtom;
121 HANDLE testThread;
122 ULONG RefCount = 0, PinCount = 0, Len = 0;
123 WCHAR Name[64];
124
125 /* If we pass a non-null string to create atom table, then it thinks that we
126 * have passed it an already allocated atom table */
127 res = pRtlCreateAtomTable(0, &AtomTable);
128 ok(!res, "RtlCreateAtomTable should succeed with an atom table size of 0\n");
129
130 if (!res)
131 {
132 res = pRtlDestroyAtomTable(AtomTable);
133 ok(!res, "We could create the atom table, but we couldn't destroy it! retval: %x\n", res);
134 }
135
136 AtomTable = NULL;
137 res = pRtlCreateAtomTable(37, &AtomTable);
138 ok(!res, "We're unable to create an atom table with a valid table size retval: %x\n", res);
139 if (!res)
140 {
141 res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1);
142 ok(!res, "We were unable to add a simple atom to the atom table, retval: %x\n", res);
143
144 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1Cap, &testAtom);
145 ok(!res, "We were unable to find capital version of the atom, retval: %x\n", res);
146 ok(Atom1 == testAtom, "Found wrong atom in table when querying capital atom\n");
147
148 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1Low, &testAtom);
149 ok(!res, "Unable to find lowercase version of the atom, retval: %x\n", res);
150 ok(testAtom == Atom1, "Found wrong atom when querying lowercase atom\n");
151
152 res = pRtlAddAtomToAtomTable(AtomTable, EmptyAtom, &testEAtom);
153 ok(res == STATUS_OBJECT_NAME_INVALID, "Got wrong retval, retval: %x\n", res);
154
155 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
156 ok(!res, "Failed to find totally legitimate atom, retval: %x\n", res);
157 ok(testAtom == Atom1, "Found wrong atom!\n");
158
159 res = pRtlAddAtomToAtomTable(AtomTable, testAtom2, &Atom2);
160 ok(!res, "Unable to add other legitimate atom to table, retval: %x\n", res);
161
162 res = pRtlPinAtomInAtomTable(AtomTable, Atom2);
163 ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
164
165 testThread = CreateThread(NULL, 0, RtlAtomTestThread, &AtomTable, 0, NULL);
166 WaitForSingleObject(testThread, INFINITE);
167
168 Len = 64;
169 res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, &RefCount, &PinCount, Name, &Len);
170 ok(!res, "Unable to query atom in atom table, retval: %x\n", res);
171 ok(RefCount == 1, "RefCount is not 1 but %x\n", RefCount);
172 ok(PinCount == 1, "PinCount is not 1 but %x\n", PinCount);
173 ok(!lstrcmpW(Name, testAtom2), "We found wrong atom\n");
174 ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %d\n", Len);
175
176 res = pRtlEmptyAtomTable(AtomTable, FALSE);
177 ok(!res, "Unable to empty atom table, retval %x\n", res);
178
179 Len = 64;
180 res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, &RefCount, &PinCount, Name, &Len);
181 ok(!res, "It seems RtlEmptyAtomTable deleted our pinned atom eaven though we asked it not to, retval: %x\n", res);
182 ok(RefCount == 1, "RefCount is not 1 but %x\n", RefCount);
183 ok(PinCount == 1, "PinCount is not 1 but %x\n", PinCount);
184 ok(!lstrcmpW(Name, testAtom2), "We found wrong atom\n");
185 ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %d\n", Len);
186
187 Len = 8;
188 Name[0] = Name[1] = Name[2] = Name[3] = Name[4] = 0x1337;
189 res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, NULL, NULL, Name, &Len);
190 ok(!res, "query atom %x\n", res);
191 ok(Len == 6, "wrong length %u\n", Len);
192 ok(!memcmp(Name, testAtom2, Len), "wrong atom string\n");
193 ok(!Name[3], "wrong string termination\n");
194 ok(Name[4] == 0x1337, "buffer overwrite\n");
195
196 Len = lstrlenW(testAtom2) * sizeof(WCHAR);
197 memset(Name, '.', sizeof(Name));
198 res = pRtlQueryAtomInAtomTable( AtomTable, Atom2, NULL, NULL, Name, &Len );
199 ok(!res, "query atom %x\n", res);
200 ok(Len == (lstrlenW(testAtom2) - 1) * sizeof(WCHAR), "wrong length %u\n", Len);
201 ok(!memcmp(testAtom2, Name, (lstrlenW(testAtom2) - 1) * sizeof(WCHAR)), "wrong atom name\n");
202 ok(Name[lstrlenW(testAtom2) - 1] == '\0', "wrong char\n");
203 ok(Name[lstrlenW(testAtom2)] == ('.' << 8) + '.', "wrong char\n");
204
205 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &testAtom);
206 ok(!res, "We can't find our pinned atom!! retval: %x\n", res);
207 ok(testAtom == Atom2, "We found wrong atom!!!\n");
208
209 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
210 ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "We found the atom in our table eaven though we asked RtlEmptyAtomTable to remove it, retval: %x\n", res);
211
212 res = pRtlAddAtomToAtomTable(AtomTable, testAtom3, &Atom3);
213 ok(!res, "Unable to add atom to table, retval: %x\n", res);
214
215 res = pRtlEmptyAtomTable(AtomTable, TRUE);
216 ok(!res, "Unable to empty atom table, retval: %x\n", res);
217
218 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &testAtom);
219 ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "The pinned atom should be removed, retval: %x\n", res);
220
221 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom3, &testAtom);
222 ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Non pinned atom should also be removed, retval: %x\n", res);
223
224 res = pRtlDestroyAtomTable(AtomTable);
225 ok(!res, "Can't destroy atom table, retval: %x\n", res);
226 }
227
228 AtomTable = NULL;
229 res = pRtlCreateAtomTable(37, &AtomTable);
230 ok(!res, "Unable to create atom table, retval: %x\n", res);
231
232 if (!res)
233 {
234 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
235 ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Didn't get expected retval with querying an empty atom table, retval: %x\n", res);
236
237 res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1);
238 ok(!res, "Unable to add atom to atom table, retval %x\n", res);
239
240 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
241 ok(!res, "Can't find previously added atom in table, retval: %x\n", res);
242 ok(testAtom == Atom1, "Found wrong atom! retval: %x\n", res);
243
244 res = pRtlDeleteAtomFromAtomTable(AtomTable, Atom1);
245 ok(!res, "Unable to delete atom from table, retval: %x\n", res);
246
247 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
248 ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Able to find previously deleted atom in table, retval: %x\n", res);
249
250 res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1);
251 ok(!res, "Unable to add atom to atom table, retval: %x\n", res);
252
253 Len = 0;
254 res = pRtlQueryAtomInAtomTable(AtomTable, Atom1, NULL, NULL, Name, &Len);
255 ok(res == STATUS_BUFFER_TOO_SMALL, "Got wrong retval, retval: %x\n", res);
256 ok((lstrlenW(testAtom1) * sizeof(WCHAR)) == Len || broken(!Len) /* nt4 */, "Got wrong length %x\n", Len);
257 if (!Len) pNtAddAtomNT4 = (void *)pNtAddAtom;
258
259 res = pRtlPinAtomInAtomTable(AtomTable, Atom1);
260 ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
261
262 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
263 ok(!res, "Unable to find atom in atom table, retval: %x\n", res);
264 ok(testAtom == Atom1, "Wrong atom found\n");
265
266 res = pRtlDeleteAtomFromAtomTable(AtomTable, Atom1);
267 ok(res == STATUS_WAS_LOCKED, "Unable to delete atom from table, retval: %x\n", res);
268
269 res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
270 ok(!res, "Able to find deleted atom in table\n");
271
272 res = pRtlDestroyAtomTable(AtomTable);
273 ok(!res, "Unable to destroy atom table\n");
274 }
275 }
276
277 /* Test Adding integer atoms to atom table */
278 static void test_NtIntAtom(void)
279 {
280 NTSTATUS res;
281 RTL_ATOM_TABLE AtomTable;
282 RTL_ATOM testAtom;
283 ULONG RefCount = 0, PinCount = 0;
284 INT_PTR i;
285 WCHAR Name[64];
286 ULONG Len;
287
288 AtomTable = NULL;
289 res = pRtlCreateAtomTable(37, &AtomTable);
290 ok(!res, "Unable to create atom table, %x\n", res);
291
292 if (!res)
293 {
294 /* According to the kernel32 functions, integer atoms are only allowed from
295 * 0x0001 to 0xbfff and not 0xc000 to 0xffff, which is correct */
296 res = pRtlAddAtomToAtomTable(AtomTable, NULL, &testAtom);
297 ok(res == STATUS_INVALID_PARAMETER, "Didn't get expected result from adding 0 int atom, retval: %x\n", res);
298 for (i = 1; i <= 0xbfff; i++)
299 {
300 res = pRtlAddAtomToAtomTable(AtomTable, (LPWSTR)i, &testAtom);
301 ok(!res, "Unable to add valid integer atom %li, retval: %x\n", i, res);
302 }
303
304 for (i = 1; i <= 0xbfff; i++)
305 {
306 res = pRtlLookupAtomInAtomTable(AtomTable, (LPWSTR)i, &testAtom);
307 ok(!res, "Unable to find int atom %li, retval: %x\n", i, res);
308 if (!res)
309 {
310 res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
311 ok(!res, "Unable to pin int atom %li, retval: %x\n", i, res);
312 }
313 }
314
315 for (i = 0xc000; i <= 0xffff; i++)
316 {
317 res = pRtlAddAtomToAtomTable(AtomTable, (LPWSTR)i, &testAtom);
318 ok(res, "Able to illeageal integer atom %li, retval: %x\n", i, res);
319 }
320
321 res = pRtlDestroyAtomTable(AtomTable);
322 ok(!res, "Unable to destroy atom table, retval: %x\n", res);
323 }
324
325 AtomTable = NULL;
326 res = pRtlCreateAtomTable(37, &AtomTable);
327 ok(!res, "Unable to create atom table, %x\n", res);
328 if (!res)
329 {
330 res = pRtlLookupAtomInAtomTable(AtomTable, (PWSTR)123, &testAtom);
331 ok(!res, "Unable to query atom in atom table, retval: %x\n", res);
332
333 res = pRtlAddAtomToAtomTable(AtomTable, testAtomInt, &testAtom);
334 ok(!res, "Unable to add int atom to table, retval: %x\n", res);
335
336 res = pRtlAddAtomToAtomTable(AtomTable, testAtomIntInv, &testAtom);
337 ok(!res, "Unable to add int atom to table, retval: %x\n", res);
338
339 res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)123, &testAtom);
340 ok(!res, "Unable to add int atom to table, retval: %x\n", res);
341
342 res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)123, &testAtom);
343 ok(!res, "Unable to re-add int atom to table, retval: %x\n", res);
344
345 Len = 64;
346 res = pRtlQueryAtomInAtomTable(AtomTable, testAtom, &RefCount, &PinCount, Name, &Len);
347 ok(!res, "Unable to query atom in atom table, retval: %x\n", res);
348 ok(PinCount == 1, "Expected pincount 1 but got %x\n", PinCount);
349 ok(RefCount == 1, "Expected refcount 1 but got %x\n", RefCount);
350 ok(!lstrcmpW(testAtomOTT, Name), "Got wrong atom name\n");
351 ok((lstrlenW(testAtomOTT) * sizeof(WCHAR)) == Len, "Got wrong len %d\n", Len);
352
353 res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
354 ok(!res, "Unable to pin int atom, retval: %x\n", res);
355
356 res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
357 ok(!res, "Unable to pin int atom, retval: %x\n", res);
358
359 res = pRtlQueryAtomInAtomTable(AtomTable, testAtom, &RefCount, &PinCount, NULL, NULL);
360 ok(!res, "Unable to query atom in atom table, retval: %x\n", res);
361 ok(PinCount == 1, "Expected pincount 1 but got %x\n", PinCount);
362 ok(RefCount == 1, "Expected refcount 1 but got %x\n", RefCount);
363
364 res = pRtlDestroyAtomTable(AtomTable);
365 ok(!res, "Unable to destroy atom table, retval: %x\n", res);
366 }
367 }
368
369 /* Tests to see how the pincount and refcount actually works */
370 static void test_NtRefPinAtom(void)
371 {
372 RTL_ATOM_TABLE AtomTable;
373 RTL_ATOM Atom;
374 ULONG PinCount = 0, RefCount = 0;
375 NTSTATUS res;
376
377 AtomTable = NULL;
378 res = pRtlCreateAtomTable(37, &AtomTable);
379 ok(!res, "Unable to create atom table, %x\n", res);
380
381 if (!res)
382 {
383 res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom);
384 ok(!res, "Unable to add our atom to the atom table, retval: %x\n", res);
385
386 res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom);
387 ok(!res, "Unable to add our atom to the atom table, retval: %x\n", res);
388
389 res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom);
390 ok(!res, "Unable to add our atom to the atom table, retval: %x\n", res);
391
392 res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, NULL, NULL);
393 ok(!res, "Unable to query atom in atom table, retval: %x\n", res);
394 ok(PinCount == 0, "Expected pincount 0 but got %x\n", PinCount);
395 ok(RefCount == 3, "Expected refcount 3 but got %x\n", RefCount);
396
397 res = pRtlPinAtomInAtomTable(AtomTable, Atom);
398 ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
399
400 res = pRtlPinAtomInAtomTable(AtomTable, Atom);
401 ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
402
403 res = pRtlPinAtomInAtomTable(AtomTable, Atom);
404 ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
405
406 res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, NULL, NULL);
407 ok(!res, "Unable to query atom in atom table, retval: %x\n", res);
408 ok(PinCount == 1, "Expected pincount 1 but got %x\n", PinCount);
409 ok(RefCount == 3, "Expected refcount 3 but got %x\n", RefCount);
410
411 res = pRtlDestroyAtomTable(AtomTable);
412 ok(!res, "Unable to destroy atom table, retval: %x\n", res);
413 }
414 }
415
416 static void test_Global(void)
417 {
418 NTSTATUS res;
419 RTL_ATOM atom;
420 ULONG ptr[(sizeof(ATOM_BASIC_INFORMATION) + 255 * sizeof(WCHAR)) / sizeof(ULONG)];
421 ATOM_BASIC_INFORMATION* abi = (ATOM_BASIC_INFORMATION*)ptr;
422 ULONG ptr_size = sizeof(ptr);
423
424 if (pNtAddAtomNT4)
425 res = pNtAddAtomNT4(testAtom1, &atom);
426 else
427 res = pNtAddAtom(testAtom1, lstrlenW(testAtom1) * sizeof(WCHAR), &atom);
428
429 ok(!res, "Added atom (%x)\n", res);
430
431 memset( ptr, 0xcc, sizeof(ptr) );
432 res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
433 ok(!res, "atom lookup\n");
434 ok(!lstrcmpW(abi->Name, testAtom1), "ok strings\n");
435 ok(abi->NameLength == lstrlenW(testAtom1) * sizeof(WCHAR), "wrong string length\n");
436 ok(abi->Name[lstrlenW(testAtom1)] == 0, "wrong string termination %x\n", abi->Name[lstrlenW(testAtom1)]);
437 ok(abi->Name[lstrlenW(testAtom1) + 1] == 0xcccc, "buffer overwrite %x\n", abi->Name[lstrlenW(testAtom1) + 1]);
438
439 ptr_size = sizeof(ATOM_BASIC_INFORMATION);
440 res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
441 ok(res == STATUS_BUFFER_TOO_SMALL, "wrong return status (%x)\n", res);
442 ok(abi->NameLength == lstrlenW(testAtom1) * sizeof(WCHAR) || broken(abi->NameLength == sizeof(WCHAR)), /* nt4 */
443 "string length %u\n",abi->NameLength);
444
445 memset( ptr, 0xcc, sizeof(ptr) );
446 ptr_size = sizeof(ATOM_BASIC_INFORMATION) + lstrlenW(testAtom1) * sizeof(WCHAR);
447 res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
448 ok(!res, "atom lookup %x\n", res);
449 ok(!lstrcmpW(abi->Name, testAtom1), "strings don't match\n");
450 ok(abi->NameLength == lstrlenW(testAtom1) * sizeof(WCHAR), "wrong string length\n");
451 ok(abi->Name[lstrlenW(testAtom1)] == 0, "buffer overwrite %x\n", abi->Name[lstrlenW(testAtom1)]);
452 ok(abi->Name[lstrlenW(testAtom1) + 1] == 0xcccc, "buffer overwrite %x\n", abi->Name[lstrlenW(testAtom1) + 1]);
453
454 memset( ptr, 0xcc, sizeof(ptr) );
455 ptr_size = sizeof(ATOM_BASIC_INFORMATION) + 4 * sizeof(WCHAR);
456 res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
457 ok(!res, "couldn't find atom\n");
458 ok(abi->NameLength == 8, "wrong string length %u\n", abi->NameLength);
459 ok(!memcmp(abi->Name, testAtom1, 8), "strings don't match\n");
460 }
461
462 START_TEST(atom)
463 {
464 InitFunctionPtr();
465 if (pRtlCreateAtomTable)
466 {
467 /* Global atom table seems to be available to GUI apps only in
468 Win7, so let's turn this app into a GUI app */
469 GetDesktopWindow();
470
471 test_NtAtom();
472 test_NtIntAtom();
473 test_NtRefPinAtom();
474 test_Global();
475 }
476 else
477 win_skip("Needed atom functions are not available\n");
478
479 FreeLibrary(hntdll);
480 }