1 /* Unit test suite for Ntdll atom API functions
3 * Copyright 2003 Gyorgy 'Nog' Jeney
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.
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.
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
20 * We use function pointers here as there is no import library for NTDLL on
28 /* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro
29 * definition errors when we get to winnt.h
31 #define WIN32_NO_STATUS
38 #include "wine/test.h"
41 #ifndef __WINE_WINTERNL_H
42 typedef unsigned short RTL_ATOM
, *PRTL_ATOM
;
43 typedef struct atom_table
*RTL_ATOM_TABLE
, **PRTL_ATOM_TABLE
;
46 /* Function pointers for ntdll calls */
47 static HMODULE hntdll
= 0;
48 static NTSTATUS (WINAPI
*pRtlCreateAtomTable
)(ULONG
,PRTL_ATOM_TABLE
);
49 static NTSTATUS (WINAPI
*pRtlDestroyAtomTable
)(RTL_ATOM_TABLE
);
50 static NTSTATUS (WINAPI
*pRtlEmptyAtomTable
)(RTL_ATOM_TABLE
,BOOLEAN
);
51 static NTSTATUS (WINAPI
*pRtlAddAtomToAtomTable
)(RTL_ATOM_TABLE
,PCWSTR
,PRTL_ATOM
);
52 static NTSTATUS (WINAPI
*pRtlDeleteAtomFromAtomTable
)(RTL_ATOM_TABLE
,RTL_ATOM
);
53 static NTSTATUS (WINAPI
*pRtlLookupAtomInAtomTable
)(RTL_ATOM_TABLE
,PCWSTR
,PRTL_ATOM
);
54 static NTSTATUS (WINAPI
*pRtlPinAtomInAtomTable
)(RTL_ATOM_TABLE
,RTL_ATOM
);
55 static NTSTATUS (WINAPI
*pRtlQueryAtomInAtomTable
)(RTL_ATOM_TABLE
,RTL_ATOM
,PULONG
,PULONG
,PWSTR
,PULONG
);
57 static NTSTATUS (WINAPI
* pNtAddAtom
)(LPCWSTR
,ULONG
,RTL_ATOM
*);
58 static NTSTATUS (WINAPI
* pNtAddAtomNT4
)(LPCWSTR
,RTL_ATOM
*);
59 static NTSTATUS (WINAPI
* pNtQueryInformationAtom
)(RTL_ATOM
,DWORD
,void*,ULONG
,PULONG
);
61 static const WCHAR EmptyAtom
[] = {0};
62 static const WCHAR testAtom1
[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
63 static const WCHAR testAtom2
[] = {'H','e','l','l','o',' ','W','o','r','l','d','2',0};
64 static const WCHAR testAtom3
[] = {'H','e','l','l','o',' ','W','o','r','l','d','3',0};
66 static const WCHAR testAtom1Cap
[] = {'H','E','L','L','O',' ','W','O','R','L','D',0};
67 static const WCHAR testAtom1Low
[] = {'h','e','l','l','o',' ','w','o','r','l','d',0};
69 static const WCHAR testAtomInt
[] = {'#','1','3','2',0};
70 static const WCHAR testAtomIntInv
[] = {'#','2','3','4','z',0};
71 static const WCHAR testAtomOTT
[] = {'#','1','2','3',0};
73 static void InitFunctionPtr(void)
75 hntdll
= LoadLibraryA("ntdll.dll");
76 ok(hntdll
!= 0, "Unable to load ntdll.dll\n");
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");
89 pNtAddAtom
= (void *)GetProcAddress(hntdll
, "NtAddAtom");
90 pNtQueryInformationAtom
= (void *)GetProcAddress(hntdll
, "NtQueryInformationAtom");
94 static DWORD WINAPI
RtlAtomTestThread(LPVOID Table
)
96 RTL_ATOM_TABLE AtomTable
= *(PRTL_ATOM_TABLE
)Table
;
99 ULONG RefCount
= 0, PinCount
= 0, Len
= 0;
102 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom1
, &Atom
);
103 ok(!res
, "Unable to find atom from another thread, retval: %x\n", res
);
105 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom2
, &Atom
);
106 ok(!res
, "Unable to lookup pinned atom in table, retval: %x\n", res
);
108 res
= pRtlQueryAtomInAtomTable(AtomTable
, Atom
, &RefCount
, &PinCount
, Name
, &Len
);
109 ok(res
== STATUS_BUFFER_TOO_SMALL
, "We got wrong retval: %x\n", res
);
112 res
= pRtlQueryAtomInAtomTable(AtomTable
, Atom
, &RefCount
, &PinCount
, Name
, &Len
);
113 ok(!res
, "Failed with long enough buffer, retval: %x\n", res
);
114 ok(RefCount
== 1, "Refcount was not 1 but %x\n", RefCount
);
115 ok(PinCount
== 1, "Pincount was not 1 but %x\n", PinCount
);
116 ok(!lstrcmpW(Name
, testAtom2
), "We found wrong atom!!\n");
117 ok((lstrlenW(testAtom2
) * sizeof(WCHAR
)) == Len
, "Returned wrong length %d\n", Len
);
120 res
= pRtlQueryAtomInAtomTable(AtomTable
, Atom
, NULL
, NULL
, Name
, &Len
);
121 ok(!res
, "RtlQueryAtomInAtomTable with optional args invalid failed, retval: %x\n", res
);
122 ok(!lstrcmpW(Name
, testAtom2
), "Found Wrong atom!\n");
123 ok((lstrlenW(testAtom2
) * sizeof(WCHAR
)) == Len
, "Returned wrong length %d\n", Len
);
125 res
= pRtlPinAtomInAtomTable(AtomTable
, Atom
);
126 ok(!res
, "Unable to pin atom in atom table, retval: %x\n", res
);
131 static void test_NtAtom(void)
133 RTL_ATOM_TABLE AtomTable
= NULL
;
135 RTL_ATOM Atom1
, Atom2
, Atom3
, testEAtom
, testAtom
;
137 ULONG RefCount
= 0, PinCount
= 0, Len
= 0;
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");
147 res
= pRtlDestroyAtomTable(AtomTable
);
148 ok(!res
, "We could create the atom table, but we couldn't destroy it! retval: %x\n", res
);
152 res
= pRtlCreateAtomTable(37, &AtomTable
);
153 ok(!res
, "We're unable to create an atom table with a valid table size retval: %x\n", res
);
156 res
= pRtlAddAtomToAtomTable(AtomTable
, testAtom1
, &Atom1
);
157 ok(!res
, "We were unable to add a simple atom to the atom table, retval: %x\n", res
);
159 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom1Cap
, &testAtom
);
160 ok(!res
, "We were unable to find capital version of the atom, retval: %x\n", res
);
161 ok(Atom1
== testAtom
, "Found wrong atom in table when querying capital atom\n");
163 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom1Low
, &testAtom
);
164 ok(!res
, "Unable to find lowercase version of the atom, retval: %x\n", res
);
165 ok(testAtom
== Atom1
, "Found wrong atom when querying lowercase atom\n");
167 res
= pRtlAddAtomToAtomTable(AtomTable
, EmptyAtom
, &testEAtom
);
168 ok(res
== STATUS_OBJECT_NAME_INVALID
, "Got wrong retval, retval: %x\n", res
);
170 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom1
, &testAtom
);
171 ok(!res
, "Failed to find totally legitimate atom, retval: %x\n", res
);
172 ok(testAtom
== Atom1
, "Found wrong atom!\n");
174 res
= pRtlAddAtomToAtomTable(AtomTable
, testAtom2
, &Atom2
);
175 ok(!res
, "Unable to add other legitimate atom to table, retval: %x\n", res
);
177 res
= pRtlPinAtomInAtomTable(AtomTable
, Atom2
);
178 ok(!res
, "Unable to pin atom in atom table, retval: %x\n", res
);
180 testThread
= CreateThread(NULL
, 0, RtlAtomTestThread
, &AtomTable
, 0, NULL
);
181 WaitForSingleObject(testThread
, INFINITE
);
184 res
= pRtlQueryAtomInAtomTable(AtomTable
, Atom2
, &RefCount
, &PinCount
, Name
, &Len
);
185 ok(!res
, "Unable to query atom in atom table, retval: %x\n", res
);
186 ok(RefCount
== 1, "RefCount is not 1 but %x\n", RefCount
);
187 ok(PinCount
== 1, "PinCount is not 1 but %x\n", PinCount
);
188 ok(!lstrcmpW(Name
, testAtom2
), "We found wrong atom\n");
189 ok((lstrlenW(testAtom2
) * sizeof(WCHAR
)) == Len
, "Returned wrong length %d\n", Len
);
191 res
= pRtlEmptyAtomTable(AtomTable
, FALSE
);
192 ok(!res
, "Unable to empty atom table, retval %x\n", res
);
195 res
= pRtlQueryAtomInAtomTable(AtomTable
, Atom2
, &RefCount
, &PinCount
, Name
, &Len
);
196 ok(!res
, "It seems RtlEmptyAtomTable deleted our pinned atom eaven though we asked it not to, retval: %x\n", res
);
197 ok(RefCount
== 1, "RefCount is not 1 but %x\n", RefCount
);
198 ok(PinCount
== 1, "PinCount is not 1 but %x\n", PinCount
);
199 ok(!lstrcmpW(Name
, testAtom2
), "We found wrong atom\n");
200 ok((lstrlenW(testAtom2
) * sizeof(WCHAR
)) == Len
, "Returned wrong length %d\n", Len
);
203 Name
[0] = Name
[1] = Name
[2] = Name
[3] = Name
[4] = 0x1337;
204 res
= pRtlQueryAtomInAtomTable(AtomTable
, Atom2
, NULL
, NULL
, Name
, &Len
);
205 ok(!res
, "query atom %x\n", res
);
206 ok(Len
== 6, "wrong length %u\n", Len
);
207 ok(!memcmp(Name
, testAtom2
, Len
), "wrong atom string\n");
208 ok(!Name
[3], "wrong string termination\n");
209 ok(Name
[4] == 0x1337, "buffer overwrite\n");
211 Len
= lstrlenW(testAtom2
) * sizeof(WCHAR
);
212 memset(Name
, '.', sizeof(Name
));
213 res
= pRtlQueryAtomInAtomTable( AtomTable
, Atom2
, NULL
, NULL
, Name
, &Len
);
214 ok(!res
, "query atom %x\n", res
);
215 ok(Len
== (lstrlenW(testAtom2
) - 1) * sizeof(WCHAR
), "wrong length %u\n", Len
);
216 ok(!memcmp(testAtom2
, Name
, (lstrlenW(testAtom2
) - 1) * sizeof(WCHAR
)), "wrong atom name\n");
217 ok(Name
[lstrlenW(testAtom2
) - 1] == '\0', "wrong char\n");
218 ok(Name
[lstrlenW(testAtom2
)] == ('.' << 8) + '.', "wrong char\n");
220 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom2
, &testAtom
);
221 ok(!res
, "We can't find our pinned atom!! retval: %x\n", res
);
222 ok(testAtom
== Atom2
, "We found wrong atom!!!\n");
224 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom1
, &testAtom
);
225 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
);
227 res
= pRtlAddAtomToAtomTable(AtomTable
, testAtom3
, &Atom3
);
228 ok(!res
, "Unable to add atom to table, retval: %x\n", res
);
230 res
= pRtlEmptyAtomTable(AtomTable
, TRUE
);
231 ok(!res
, "Unable to empty atom table, retval: %x\n", res
);
233 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom2
, &testAtom
);
234 ok(res
== STATUS_OBJECT_NAME_NOT_FOUND
, "The pinned atom should be removed, retval: %x\n", res
);
236 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom3
, &testAtom
);
237 ok(res
== STATUS_OBJECT_NAME_NOT_FOUND
, "Non pinned atom should also be removed, retval: %x\n", res
);
239 res
= pRtlDestroyAtomTable(AtomTable
);
240 ok(!res
, "Can't destroy atom table, retval: %x\n", res
);
244 res
= pRtlCreateAtomTable(37, &AtomTable
);
245 ok(!res
, "Unable to create atom table, retval: %x\n", res
);
249 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom1
, &testAtom
);
250 ok(res
== STATUS_OBJECT_NAME_NOT_FOUND
, "Didn't get expected retval with querying an empty atom table, retval: %x\n", res
);
252 res
= pRtlAddAtomToAtomTable(AtomTable
, testAtom1
, &Atom1
);
253 ok(!res
, "Unable to add atom to atom table, retval %x\n", res
);
255 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom1
, &testAtom
);
256 ok(!res
, "Can't find previously added atom in table, retval: %x\n", res
);
257 ok(testAtom
== Atom1
, "Found wrong atom! retval: %x\n", res
);
259 res
= pRtlDeleteAtomFromAtomTable(AtomTable
, Atom1
);
260 ok(!res
, "Unable to delete atom from table, retval: %x\n", res
);
262 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom1
, &testAtom
);
263 ok(res
== STATUS_OBJECT_NAME_NOT_FOUND
, "Able to find previously deleted atom in table, retval: %x\n", res
);
265 res
= pRtlAddAtomToAtomTable(AtomTable
, testAtom1
, &Atom1
);
266 ok(!res
, "Unable to add atom to atom table, retval: %x\n", res
);
269 res
= pRtlQueryAtomInAtomTable(AtomTable
, Atom1
, NULL
, NULL
, Name
, &Len
);
270 ok(res
== STATUS_BUFFER_TOO_SMALL
, "Got wrong retval, retval: %x\n", res
);
271 ok((lstrlenW(testAtom1
) * sizeof(WCHAR
)) == Len
|| broken(!Len
) /* nt4 */, "Got wrong length %x\n", Len
);
272 if (!Len
) pNtAddAtomNT4
= (void *)pNtAddAtom
;
274 res
= pRtlPinAtomInAtomTable(AtomTable
, Atom1
);
275 ok(!res
, "Unable to pin atom in atom table, retval: %x\n", res
);
277 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom1
, &testAtom
);
278 ok(!res
, "Unable to find atom in atom table, retval: %x\n", res
);
279 ok(testAtom
== Atom1
, "Wrong atom found\n");
281 res
= pRtlDeleteAtomFromAtomTable(AtomTable
, Atom1
);
282 ok(res
== STATUS_WAS_LOCKED
, "Unable to delete atom from table, retval: %x\n", res
);
284 res
= pRtlLookupAtomInAtomTable(AtomTable
, testAtom1
, &testAtom
);
285 ok(!res
, "Able to find deleted atom in table\n");
287 res
= pRtlDestroyAtomTable(AtomTable
);
288 ok(!res
, "Unable to destroy atom table\n");
292 /* Test Adding integer atoms to atom table */
293 static void test_NtIntAtom(void)
296 RTL_ATOM_TABLE AtomTable
;
298 ULONG RefCount
= 0, PinCount
= 0;
304 res
= pRtlCreateAtomTable(37, &AtomTable
);
305 ok(!res
, "Unable to create atom table, %x\n", res
);
309 /* According to the kernel32 functions, integer atoms are only allowed from
310 * 0x0001 to 0xbfff and not 0xc000 to 0xffff, which is correct */
311 res
= pRtlAddAtomToAtomTable(AtomTable
, NULL
, &testAtom
);
312 ok(res
== STATUS_INVALID_PARAMETER
, "Didn't get expected result from adding 0 int atom, retval: %x\n", res
);
313 for (i
= 1; i
<= 0xbfff; i
++)
315 res
= pRtlAddAtomToAtomTable(AtomTable
, (LPWSTR
)i
, &testAtom
);
316 ok(!res
, "Unable to add valid integer atom %li, retval: %x\n", i
, res
);
319 for (i
= 1; i
<= 0xbfff; i
++)
321 res
= pRtlLookupAtomInAtomTable(AtomTable
, (LPWSTR
)i
, &testAtom
);
322 ok(!res
, "Unable to find int atom %li, retval: %x\n", i
, res
);
325 res
= pRtlPinAtomInAtomTable(AtomTable
, testAtom
);
326 ok(!res
, "Unable to pin int atom %li, retval: %x\n", i
, res
);
330 for (i
= 0xc000; i
<= 0xffff; i
++)
332 res
= pRtlAddAtomToAtomTable(AtomTable
, (LPWSTR
)i
, &testAtom
);
333 ok(res
, "Able to illeageal integer atom %li, retval: %x\n", i
, res
);
336 res
= pRtlDestroyAtomTable(AtomTable
);
337 ok(!res
, "Unable to destroy atom table, retval: %x\n", res
);
341 res
= pRtlCreateAtomTable(37, &AtomTable
);
342 ok(!res
, "Unable to create atom table, %x\n", res
);
345 res
= pRtlLookupAtomInAtomTable(AtomTable
, (PWSTR
)123, &testAtom
);
346 ok(!res
, "Unable to query atom in atom table, retval: %x\n", res
);
348 res
= pRtlAddAtomToAtomTable(AtomTable
, testAtomInt
, &testAtom
);
349 ok(!res
, "Unable to add int atom to table, retval: %x\n", res
);
351 res
= pRtlAddAtomToAtomTable(AtomTable
, testAtomIntInv
, &testAtom
);
352 ok(!res
, "Unable to add int atom to table, retval: %x\n", res
);
354 res
= pRtlAddAtomToAtomTable(AtomTable
, (PWSTR
)123, &testAtom
);
355 ok(!res
, "Unable to add int atom to table, retval: %x\n", res
);
357 res
= pRtlAddAtomToAtomTable(AtomTable
, (PWSTR
)123, &testAtom
);
358 ok(!res
, "Unable to re-add int atom to table, retval: %x\n", res
);
361 res
= pRtlQueryAtomInAtomTable(AtomTable
, testAtom
, &RefCount
, &PinCount
, Name
, &Len
);
362 ok(!res
, "Unable to query atom in atom table, retval: %x\n", res
);
363 ok(PinCount
== 1, "Expected pincount 1 but got %x\n", PinCount
);
364 ok(RefCount
== 1, "Expected refcount 1 but got %x\n", RefCount
);
365 ok(!lstrcmpW(testAtomOTT
, Name
), "Got wrong atom name\n");
366 ok((lstrlenW(testAtomOTT
) * sizeof(WCHAR
)) == Len
, "Got wrong len %d\n", Len
);
368 res
= pRtlPinAtomInAtomTable(AtomTable
, testAtom
);
369 ok(!res
, "Unable to pin int atom, retval: %x\n", res
);
371 res
= pRtlPinAtomInAtomTable(AtomTable
, testAtom
);
372 ok(!res
, "Unable to pin int atom, retval: %x\n", res
);
374 res
= pRtlQueryAtomInAtomTable(AtomTable
, testAtom
, &RefCount
, &PinCount
, NULL
, NULL
);
375 ok(!res
, "Unable to query atom in atom table, retval: %x\n", res
);
376 ok(PinCount
== 1, "Expected pincount 1 but got %x\n", PinCount
);
377 ok(RefCount
== 1, "Expected refcount 1 but got %x\n", RefCount
);
379 res
= pRtlDestroyAtomTable(AtomTable
);
380 ok(!res
, "Unable to destroy atom table, retval: %x\n", res
);
384 /* Tests to see how the pincount and refcount actually works */
385 static void test_NtRefPinAtom(void)
387 RTL_ATOM_TABLE AtomTable
;
389 ULONG PinCount
= 0, RefCount
= 0;
393 res
= pRtlCreateAtomTable(37, &AtomTable
);
394 ok(!res
, "Unable to create atom table, %x\n", res
);
398 res
= pRtlAddAtomToAtomTable(AtomTable
, testAtom1
, &Atom
);
399 ok(!res
, "Unable to add our atom to the atom table, retval: %x\n", res
);
401 res
= pRtlAddAtomToAtomTable(AtomTable
, testAtom1
, &Atom
);
402 ok(!res
, "Unable to add our atom to the atom table, retval: %x\n", res
);
404 res
= pRtlAddAtomToAtomTable(AtomTable
, testAtom1
, &Atom
);
405 ok(!res
, "Unable to add our atom to the atom table, retval: %x\n", res
);
407 res
= pRtlQueryAtomInAtomTable(AtomTable
, Atom
, &RefCount
, &PinCount
, NULL
, NULL
);
408 ok(!res
, "Unable to query atom in atom table, retval: %x\n", res
);
409 ok(PinCount
== 0, "Expected pincount 0 but got %x\n", PinCount
);
410 ok(RefCount
== 3, "Expected refcount 3 but got %x\n", RefCount
);
412 res
= pRtlPinAtomInAtomTable(AtomTable
, Atom
);
413 ok(!res
, "Unable to pin atom in atom table, retval: %x\n", res
);
415 res
= pRtlPinAtomInAtomTable(AtomTable
, Atom
);
416 ok(!res
, "Unable to pin atom in atom table, retval: %x\n", res
);
418 res
= pRtlPinAtomInAtomTable(AtomTable
, Atom
);
419 ok(!res
, "Unable to pin atom in atom table, retval: %x\n", res
);
421 res
= pRtlQueryAtomInAtomTable(AtomTable
, Atom
, &RefCount
, &PinCount
, NULL
, NULL
);
422 ok(!res
, "Unable to query atom in atom table, retval: %x\n", res
);
423 ok(PinCount
== 1, "Expected pincount 1 but got %x\n", PinCount
);
424 ok(RefCount
== 3, "Expected refcount 3 but got %x\n", RefCount
);
426 res
= pRtlDestroyAtomTable(AtomTable
);
427 ok(!res
, "Unable to destroy atom table, retval: %x\n", res
);
431 static void test_Global(void)
435 char ptr
[sizeof(ATOM_BASIC_INFORMATION
) + 255 * sizeof(WCHAR
)];
436 ATOM_BASIC_INFORMATION
* abi
= (ATOM_BASIC_INFORMATION
*)ptr
;
437 ULONG ptr_size
= sizeof(ATOM_BASIC_INFORMATION
) + 255 * sizeof(WCHAR
);
440 res
= pNtAddAtomNT4(testAtom1
, &atom
);
442 res
= pNtAddAtom(testAtom1
, lstrlenW(testAtom1
) * sizeof(WCHAR
), &atom
);
444 ok(!res
, "Added atom (%x)\n", res
);
446 memset( ptr
, 0xcc, sizeof(ptr
) );
447 res
= pNtQueryInformationAtom( atom
, AtomBasicInformation
, (void*)ptr
, ptr_size
, NULL
);
448 ok(!res
, "atom lookup\n");
449 ok(!lstrcmpW(abi
->Name
, testAtom1
), "ok strings\n");
450 ok(abi
->NameLength
== lstrlenW(testAtom1
) * sizeof(WCHAR
), "wrong string length\n");
451 ok(abi
->Name
[lstrlenW(testAtom1
)] == 0, "wrong string termination %x\n", abi
->Name
[lstrlenW(testAtom1
)]);
452 ok(abi
->Name
[lstrlenW(testAtom1
) + 1] == 0xcccc, "buffer overwrite %x\n", abi
->Name
[lstrlenW(testAtom1
) + 1]);
454 ptr_size
= sizeof(ATOM_BASIC_INFORMATION
);
455 res
= pNtQueryInformationAtom( atom
, AtomBasicInformation
, (void*)ptr
, ptr_size
, NULL
);
456 ok(res
== STATUS_BUFFER_TOO_SMALL
, "wrong return status (%x)\n", res
);
457 ok(abi
->NameLength
== lstrlenW(testAtom1
) * sizeof(WCHAR
) || broken(abi
->NameLength
== sizeof(WCHAR
)), /* nt4 */
458 "string length %u\n",abi
->NameLength
);
460 memset( ptr
, 0xcc, sizeof(ptr
) );
461 ptr_size
= sizeof(ATOM_BASIC_INFORMATION
) + lstrlenW(testAtom1
) * sizeof(WCHAR
);
462 res
= pNtQueryInformationAtom( atom
, AtomBasicInformation
, (void*)ptr
, ptr_size
, NULL
);
463 ok(!res
, "atom lookup %x\n", res
);
464 ok(!lstrcmpW(abi
->Name
, testAtom1
), "strings don't match\n");
465 ok(abi
->NameLength
== lstrlenW(testAtom1
) * sizeof(WCHAR
), "wrong string length\n");
466 ok(abi
->Name
[lstrlenW(testAtom1
)] == 0, "buffer overwrite %x\n", abi
->Name
[lstrlenW(testAtom1
)]);
467 ok(abi
->Name
[lstrlenW(testAtom1
) + 1] == 0xcccc, "buffer overwrite %x\n", abi
->Name
[lstrlenW(testAtom1
) + 1]);
469 memset( ptr
, 0xcc, sizeof(ptr
) );
470 ptr_size
= sizeof(ATOM_BASIC_INFORMATION
) + 4 * sizeof(WCHAR
);
471 res
= pNtQueryInformationAtom( atom
, AtomBasicInformation
, (void*)ptr
, ptr_size
, NULL
);
472 ok(!res
, "couldn't find atom\n");
473 ok(abi
->NameLength
== 8, "wrong string length %u\n", abi
->NameLength
);
474 ok(!memcmp(abi
->Name
, testAtom1
, 8), "strings don't match\n");
480 if (pRtlCreateAtomTable
)
482 /* Global atom table seems to be available to GUI apps only in
483 Win7, so let's turn this app into a GUI app */
492 win_skip("Needed atom functions are not available\n");