ReactOS  0.4.14-dev-552-g2fad488
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
42 typedef unsigned short RTL_ATOM, *PRTL_ATOM;
43 typedef struct atom_table *RTL_ATOM_TABLE, **PRTL_ATOM_TABLE;
44 #endif
45 
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);
56 
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);
60 
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};
65 
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};
68 
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};
72 
73 static 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 {
96  RTL_ATOM_TABLE AtomTable = *(PRTL_ATOM_TABLE)Table;
97  RTL_ATOM Atom;
98  NTSTATUS res;
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: %x\n", res);
104 
105  res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &Atom);
106  ok(!res, "Unable to lookup pinned atom in table, retval: %x\n", res);
107 
108  res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, Name, &Len);
109  ok(res == STATUS_BUFFER_TOO_SMALL, "We got wrong retval: %x\n", res);
110 
111  Len = 64;
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);
118 
119  Len = 64;
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);
124 
125  res = pRtlPinAtomInAtomTable(AtomTable, Atom);
126  ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
127 
128  return 0;
129 }
130 
131 static void test_NtAtom(void)
132 {
133  RTL_ATOM_TABLE AtomTable = NULL;
134  NTSTATUS res;
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: %x\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: %x\n", res);
154  if (!res)
155  {
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);
158 
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");
162 
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");
166 
167  res = pRtlAddAtomToAtomTable(AtomTable, EmptyAtom, &testEAtom);
168  ok(res == STATUS_OBJECT_NAME_INVALID, "Got wrong retval, retval: %x\n", res);
169 
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");
173 
174  res = pRtlAddAtomToAtomTable(AtomTable, testAtom2, &Atom2);
175  ok(!res, "Unable to add other legitimate atom to table, retval: %x\n", res);
176 
177  res = pRtlPinAtomInAtomTable(AtomTable, Atom2);
178  ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
179 
180  testThread = CreateThread(NULL, 0, RtlAtomTestThread, &AtomTable, 0, NULL);
181  WaitForSingleObject(testThread, INFINITE);
182  CloseHandle(testThread);
183 
184  Len = 64;
185  res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, &RefCount, &PinCount, Name, &Len);
186  ok(!res, "Unable to query atom in atom table, retval: %x\n", res);
187  ok(RefCount == 1, "RefCount is not 1 but %x\n", RefCount);
188  ok(PinCount == 1, "PinCount is not 1 but %x\n", PinCount);
189  ok(!lstrcmpW(Name, testAtom2), "We found wrong atom\n");
190  ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %d\n", Len);
191 
192  res = pRtlEmptyAtomTable(AtomTable, FALSE);
193  ok(!res, "Unable to empty atom table, retval %x\n", res);
194 
195  Len = 64;
196  res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, &RefCount, &PinCount, Name, &Len);
197  ok(!res, "It seems RtlEmptyAtomTable deleted our pinned atom eaven though we asked it not to, retval: %x\n", res);
198  ok(RefCount == 1, "RefCount is not 1 but %x\n", RefCount);
199  ok(PinCount == 1, "PinCount is not 1 but %x\n", PinCount);
200  ok(!lstrcmpW(Name, testAtom2), "We found wrong atom\n");
201  ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %d\n", Len);
202 
203  Len = 8;
204  Name[0] = Name[1] = Name[2] = Name[3] = Name[4] = 0x1337;
205  res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, NULL, NULL, Name, &Len);
206  ok(!res, "query atom %x\n", res);
207  ok(Len == 6, "wrong length %u\n", Len);
208  ok(!memcmp(Name, testAtom2, Len), "wrong atom string\n");
209  ok(!Name[3], "wrong string termination\n");
210  ok(Name[4] == 0x1337, "buffer overwrite\n");
211 
212  Len = lstrlenW(testAtom2) * sizeof(WCHAR);
213  memset(Name, '.', sizeof(Name));
214  res = pRtlQueryAtomInAtomTable( AtomTable, Atom2, NULL, NULL, Name, &Len );
215  ok(!res, "query atom %x\n", res);
216  ok(Len == (lstrlenW(testAtom2) - 1) * sizeof(WCHAR), "wrong length %u\n", Len);
217  ok(!memcmp(testAtom2, Name, (lstrlenW(testAtom2) - 1) * sizeof(WCHAR)), "wrong atom name\n");
218  ok(Name[lstrlenW(testAtom2) - 1] == '\0', "wrong char\n");
219  ok(Name[lstrlenW(testAtom2)] == ('.' << 8) + '.', "wrong char\n");
220 
221  res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &testAtom);
222  ok(!res, "We can't find our pinned atom!! retval: %x\n", res);
223  ok(testAtom == Atom2, "We found wrong atom!!!\n");
224 
225  res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
226  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 
228  res = pRtlAddAtomToAtomTable(AtomTable, testAtom3, &Atom3);
229  ok(!res, "Unable to add atom to table, retval: %x\n", res);
230 
231  res = pRtlEmptyAtomTable(AtomTable, TRUE);
232  ok(!res, "Unable to empty atom table, retval: %x\n", res);
233 
234  res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &testAtom);
235  ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "The pinned atom should be removed, retval: %x\n", res);
236 
237  res = pRtlLookupAtomInAtomTable(AtomTable, testAtom3, &testAtom);
238  ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Non pinned atom should also be removed, retval: %x\n", res);
239 
240  res = pRtlDestroyAtomTable(AtomTable);
241  ok(!res, "Can't destroy atom table, retval: %x\n", res);
242  }
243 
244  AtomTable = NULL;
245  res = pRtlCreateAtomTable(37, &AtomTable);
246  ok(!res, "Unable to create atom table, retval: %x\n", res);
247 
248  if (!res)
249  {
250  res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
251  ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Didn't get expected retval with querying an empty atom table, retval: %x\n", res);
252 
253  res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1);
254  ok(!res, "Unable to add atom to atom table, retval %x\n", res);
255 
256  res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
257  ok(!res, "Can't find previously added atom in table, retval: %x\n", res);
258  ok(testAtom == Atom1, "Found wrong atom! retval: %x\n", res);
259 
260  res = pRtlDeleteAtomFromAtomTable(AtomTable, Atom1);
261  ok(!res, "Unable to delete atom from table, retval: %x\n", res);
262 
263  res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
264  ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Able to find previously deleted atom in table, retval: %x\n", res);
265 
266  res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1);
267  ok(!res, "Unable to add atom to atom table, retval: %x\n", res);
268 
269  Len = 0;
270  res = pRtlQueryAtomInAtomTable(AtomTable, Atom1, NULL, NULL, Name, &Len);
271  ok(res == STATUS_BUFFER_TOO_SMALL, "Got wrong retval, retval: %x\n", res);
272  ok((lstrlenW(testAtom1) * sizeof(WCHAR)) == Len || broken(!Len) /* nt4 */, "Got wrong length %x\n", Len);
273  if (!Len) pNtAddAtomNT4 = (void *)pNtAddAtom;
274 
275  res = pRtlPinAtomInAtomTable(AtomTable, Atom1);
276  ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
277 
278  res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
279  ok(!res, "Unable to find atom in atom table, retval: %x\n", res);
280  ok(testAtom == Atom1, "Wrong atom found\n");
281 
282  res = pRtlDeleteAtomFromAtomTable(AtomTable, Atom1);
283  ok(res == STATUS_WAS_LOCKED, "Unable to delete atom from table, retval: %x\n", res);
284 
285  res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
286  ok(!res, "Able to find deleted atom in table\n");
287 
288  res = pRtlDestroyAtomTable(AtomTable);
289  ok(!res, "Unable to destroy atom table\n");
290  }
291 }
292 
293 /* Test Adding integer atoms to atom table */
294 static void test_NtIntAtom(void)
295 {
296  NTSTATUS res;
297  RTL_ATOM_TABLE AtomTable;
298  RTL_ATOM testAtom;
299  ULONG RefCount = 0, PinCount = 0;
300  INT_PTR i;
301  WCHAR Name[64];
302  ULONG Len;
303 
304  AtomTable = NULL;
305  res = pRtlCreateAtomTable(37, &AtomTable);
306  ok(!res, "Unable to create atom table, %x\n", res);
307 
308  if (!res)
309  {
310  /* According to the kernel32 functions, integer atoms are only allowed from
311  * 0x0001 to 0xbfff and not 0xc000 to 0xffff, which is correct */
312  res = pRtlAddAtomToAtomTable(AtomTable, NULL, &testAtom);
313  ok(res == STATUS_INVALID_PARAMETER, "Didn't get expected result from adding 0 int atom, retval: %x\n", res);
314  for (i = 1; i <= 0xbfff; i++)
315  {
316  res = pRtlAddAtomToAtomTable(AtomTable, (LPWSTR)i, &testAtom);
317  ok(!res, "Unable to add valid integer atom %li, retval: %x\n", i, res);
318  }
319 
320  for (i = 1; i <= 0xbfff; i++)
321  {
322  res = pRtlLookupAtomInAtomTable(AtomTable, (LPWSTR)i, &testAtom);
323  ok(!res, "Unable to find int atom %li, retval: %x\n", i, res);
324  if (!res)
325  {
326  res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
327  ok(!res, "Unable to pin int atom %li, retval: %x\n", i, res);
328  }
329  }
330 
331  for (i = 0xc000; i <= 0xffff; i++)
332  {
333  res = pRtlAddAtomToAtomTable(AtomTable, (LPWSTR)i, &testAtom);
334  ok(res, "Able to illeageal integer atom %li, retval: %x\n", i, res);
335  }
336 
337  res = pRtlDestroyAtomTable(AtomTable);
338  ok(!res, "Unable to destroy atom table, retval: %x\n", res);
339  }
340 
341  AtomTable = NULL;
342  res = pRtlCreateAtomTable(37, &AtomTable);
343  ok(!res, "Unable to create atom table, %x\n", res);
344  if (!res)
345  {
346  res = pRtlLookupAtomInAtomTable(AtomTable, (PWSTR)123, &testAtom);
347  ok(!res, "Unable to query atom in atom table, retval: %x\n", res);
348 
349  res = pRtlAddAtomToAtomTable(AtomTable, testAtomInt, &testAtom);
350  ok(!res, "Unable to add int atom to table, retval: %x\n", res);
351 
352  res = pRtlAddAtomToAtomTable(AtomTable, testAtomIntInv, &testAtom);
353  ok(!res, "Unable to add int atom to table, retval: %x\n", res);
354 
355  res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)123, &testAtom);
356  ok(!res, "Unable to add int atom to table, retval: %x\n", res);
357 
358  res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)123, &testAtom);
359  ok(!res, "Unable to re-add int atom to table, retval: %x\n", res);
360 
361  Len = 64;
362  res = pRtlQueryAtomInAtomTable(AtomTable, testAtom, &RefCount, &PinCount, Name, &Len);
363  ok(!res, "Unable to query atom in atom table, retval: %x\n", res);
364  ok(PinCount == 1, "Expected pincount 1 but got %x\n", PinCount);
365  ok(RefCount == 1, "Expected refcount 1 but got %x\n", RefCount);
366  ok(!lstrcmpW(testAtomOTT, Name), "Got wrong atom name\n");
367  ok((lstrlenW(testAtomOTT) * sizeof(WCHAR)) == Len, "Got wrong len %d\n", Len);
368 
369  res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
370  ok(!res, "Unable to pin int atom, retval: %x\n", res);
371 
372  res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
373  ok(!res, "Unable to pin int atom, retval: %x\n", res);
374 
375  res = pRtlQueryAtomInAtomTable(AtomTable, testAtom, &RefCount, &PinCount, NULL, NULL);
376  ok(!res, "Unable to query atom in atom table, retval: %x\n", res);
377  ok(PinCount == 1, "Expected pincount 1 but got %x\n", PinCount);
378  ok(RefCount == 1, "Expected refcount 1 but got %x\n", RefCount);
379 
380  res = pRtlDestroyAtomTable(AtomTable);
381  ok(!res, "Unable to destroy atom table, retval: %x\n", res);
382  }
383 }
384 
385 /* Tests to see how the pincount and refcount actually works */
386 static void test_NtRefPinAtom(void)
387 {
388  RTL_ATOM_TABLE AtomTable;
389  RTL_ATOM Atom;
390  ULONG PinCount = 0, RefCount = 0;
391  NTSTATUS res;
392 
393  AtomTable = NULL;
394  res = pRtlCreateAtomTable(37, &AtomTable);
395  ok(!res, "Unable to create atom table, %x\n", res);
396 
397  if (!res)
398  {
399  res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom);
400  ok(!res, "Unable to add our atom to the atom table, retval: %x\n", res);
401 
402  res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom);
403  ok(!res, "Unable to add our atom to the atom table, retval: %x\n", res);
404 
405  res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom);
406  ok(!res, "Unable to add our atom to the atom table, retval: %x\n", res);
407 
408  res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, NULL, NULL);
409  ok(!res, "Unable to query atom in atom table, retval: %x\n", res);
410  ok(PinCount == 0, "Expected pincount 0 but got %x\n", PinCount);
411  ok(RefCount == 3, "Expected refcount 3 but got %x\n", RefCount);
412 
413  res = pRtlPinAtomInAtomTable(AtomTable, Atom);
414  ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
415 
416  res = pRtlPinAtomInAtomTable(AtomTable, Atom);
417  ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
418 
419  res = pRtlPinAtomInAtomTable(AtomTable, Atom);
420  ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
421 
422  res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, NULL, NULL);
423  ok(!res, "Unable to query atom in atom table, retval: %x\n", res);
424  ok(PinCount == 1, "Expected pincount 1 but got %x\n", PinCount);
425  ok(RefCount == 3, "Expected refcount 3 but got %x\n", RefCount);
426 
427  res = pRtlDestroyAtomTable(AtomTable);
428  ok(!res, "Unable to destroy atom table, retval: %x\n", res);
429  }
430 }
431 
432 static void test_Global(void)
433 {
434  NTSTATUS res;
435  RTL_ATOM atom;
436  ULONG ptr[(sizeof(ATOM_BASIC_INFORMATION) + 255 * sizeof(WCHAR)) / sizeof(ULONG)];
438  ULONG ptr_size = sizeof(ptr);
439 
440  if (pNtAddAtomNT4)
441  res = pNtAddAtomNT4(testAtom1, &atom);
442  else
443  res = pNtAddAtom(testAtom1, lstrlenW(testAtom1) * sizeof(WCHAR), &atom);
444 
445  ok(!res, "Added atom (%x)\n", res);
446 
447  memset( ptr, 0xcc, sizeof(ptr) );
448  res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
449  ok(!res, "atom lookup\n");
450  ok(!lstrcmpW(abi->Name, testAtom1), "ok strings\n");
451  ok(abi->NameLength == lstrlenW(testAtom1) * sizeof(WCHAR), "wrong string length\n");
452  ok(abi->Name[lstrlenW(testAtom1)] == 0, "wrong string termination %x\n", abi->Name[lstrlenW(testAtom1)]);
453  ok(abi->Name[lstrlenW(testAtom1) + 1] == 0xcccc, "buffer overwrite %x\n", abi->Name[lstrlenW(testAtom1) + 1]);
454 
456  res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
457  ok(res == STATUS_BUFFER_TOO_SMALL, "wrong return status (%x)\n", res);
458  ok(abi->NameLength == lstrlenW(testAtom1) * sizeof(WCHAR) || broken(abi->NameLength == sizeof(WCHAR)), /* nt4 */
459  "string length %u\n",abi->NameLength);
460 
461  memset( ptr, 0xcc, sizeof(ptr) );
462  ptr_size = sizeof(ATOM_BASIC_INFORMATION) + lstrlenW(testAtom1) * sizeof(WCHAR);
463  res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
464  ok(!res, "atom lookup %x\n", res);
465  ok(!lstrcmpW(abi->Name, testAtom1), "strings don't match\n");
466  ok(abi->NameLength == lstrlenW(testAtom1) * sizeof(WCHAR), "wrong string length\n");
467  ok(abi->Name[lstrlenW(testAtom1)] == 0, "buffer overwrite %x\n", abi->Name[lstrlenW(testAtom1)]);
468  ok(abi->Name[lstrlenW(testAtom1) + 1] == 0xcccc, "buffer overwrite %x\n", abi->Name[lstrlenW(testAtom1) + 1]);
469 
470  memset( ptr, 0xcc, sizeof(ptr) );
471  ptr_size = sizeof(ATOM_BASIC_INFORMATION) + 4 * sizeof(WCHAR);
472  res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
473  ok(!res, "couldn't find atom\n");
474  ok(abi->NameLength == 8, "wrong string length %u\n", abi->NameLength);
475  ok(!memcmp(abi->Name, testAtom1, 8), "strings don't match\n");
476 }
477 
479 {
480  InitFunctionPtr();
481  if (pRtlCreateAtomTable)
482  {
483  /* Global atom table seems to be available to GUI apps only in
484  Win7, so let's turn this app into a GUI app */
486 
487  test_NtAtom();
488  test_NtIntAtom();
490  test_Global();
491  }
492  else
493  win_skip("Needed atom functions are not available\n");
494 
496 }
static void test_NtAtom(void)
Definition: atom.c:131
static PWSTR
Definition: atom.c:55
ASMGENDATA Table[]
Definition: genincdata.c:61
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:406
unsigned short RTL_ATOM
Definition: atom.c:42
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static void test_NtRefPinAtom(void)
Definition: atom.c:386
static PCWSTR
Definition: atom.c:51
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
static void test_Global(void)
Definition: atom.c:432
uint16_t * PWSTR
Definition: typedefs.h:54
static HMODULE hntdll
Definition: atom.c:47
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
static BOOLEAN
Definition: atom.c:50
static RTL_ATOM *static RTL_ATOM *static DWORD
Definition: atom.c:59
LONG NTSTATUS
Definition: precomp.h:26
static const DWORD ptr_size
Definition: registry.c:42
static NTSTATUS(WINAPI *pRtlCreateAtomTable)(ULONG
START_TEST(atom)
Definition: atom.c:587
int32_t INT_PTR
Definition: typedefs.h:62
_Out_ RTL_ATOM * Atom
Definition: class.h:54
_In_ const GUID _In_ ULONG PinCount
Definition: strmini.h:504
#define lstrlenW
Definition: compat.h:415
static const WCHAR testAtomIntInv[]
Definition: atom.c:70
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
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
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
static PVOID ptr
Definition: dispmode.c:27
static const WCHAR EmptyAtom[]
Definition: atom.c:61
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:136
static const WCHAR testAtom1Cap[]
Definition: atom.c:66
smooth NULL
Definition: ftsmooth.c:416
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:652
static const WCHAR testAtom1Low[]
Definition: atom.c:67
static const WCHAR testAtom3[]
Definition: atom.c:64
static ATOM Atom2
Definition: SetProp.c:10
static ULONG
Definition: atom.c:57
static void test_NtIntAtom(void)
Definition: atom.c:294
#define FreeLibrary(x)
Definition: compat.h:413
__wchar_t WCHAR
Definition: xmlstorage.h:180
static PULONG
Definition: atom.c:55
#define WINAPI
Definition: msvc.h:8
unsigned long DWORD
Definition: ntddk_ex.h:95
#define Len
Definition: deflate.h:82
struct atom_table * RTL_ATOM_TABLE
Definition: atom.c:43
static const WCHAR testAtomOTT[]
Definition: atom.c:71
static const WCHAR testAtomInt[]
Definition: atom.c:69
static void InitFunctionPtr(void)
Definition: atom.c:73
struct _ATOM_BASIC_INFORMATION ATOM_BASIC_INFORMATION
struct atom_table ** PRTL_ATOM_TABLE
Definition: atom.c:43
unsigned short * PRTL_ATOM
Definition: atom.c:42
#define broken(x)
Definition: _sntprintf.h:21
static ATOM Atom3
Definition: SetProp.c:10
static ATOM Atom1
Definition: SetProp.c:10
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_WAS_LOCKED
Definition: ntstatus.h:139
#define ok(value,...)
Definition: atltest.h:57
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
static const WCHAR testAtom2[]
Definition: atom.c:63
static DWORD WINAPI RtlAtomTestThread(LPVOID Table)
Definition: atom.c:94
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1
#define GetProcAddress(x, y)
Definition: compat.h:418
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define INFINITE
Definition: serial.h:102
#define memset(x, y, z)
Definition: compat.h:39
#define win_skip
Definition: test.h:150
static const WCHAR testAtom1[]
Definition: atom.c:62