4836f46defc28ce14bae31207cecd2613befead5
[reactos.git] / rostests / winetests / scrrun / dictionary.c
1 /*
2 * Copyright (C) 2012 Alistair Leslie-Hughes
3 * Copyright 2015 Nikolay Sivov for CodeWeavers
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
20 #define COBJMACROS
21 #include <stdio.h>
22
23 #include "windows.h"
24 #include "ole2.h"
25 #include "oleauto.h"
26 #include "olectl.h"
27 #include "dispex.h"
28
29 #include "wine/test.h"
30
31 #include "scrrun.h"
32
33 static void test_interfaces(void)
34 {
35 static const WCHAR key_add[] = {'a', 0};
36 static const WCHAR key_add_value[] = {'a', 0};
37 static const WCHAR key_non_exist[] = {'b', 0};
38 HRESULT hr;
39 IDispatch *disp;
40 IDispatchEx *dispex;
41 IDictionary *dict;
42 IObjectWithSite *site;
43 VARIANT key, value;
44 VARIANT_BOOL exists;
45 LONG count = 0;
46
47 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
48 &IID_IDispatch, (void**)&disp);
49 ok(hr == S_OK, "got 0x%08x\n", hr);
50
51 VariantInit(&key);
52 VariantInit(&value);
53
54 hr = IDispatch_QueryInterface(disp, &IID_IDictionary, (void**)&dict);
55 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
56
57 hr = IDispatch_QueryInterface(disp, &IID_IObjectWithSite, (void**)&site);
58 ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE);
59
60 hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
61 ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE);
62
63 V_VT(&key) = VT_BSTR;
64 V_BSTR(&key) = SysAllocString(key_add);
65 V_VT(&value) = VT_BSTR;
66 V_BSTR(&value) = SysAllocString(key_add_value);
67 hr = IDictionary_Add(dict, &key, &value);
68 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
69 VariantClear(&value);
70
71 exists = VARIANT_FALSE;
72 hr = IDictionary_Exists(dict, &key, &exists);
73 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
74 ok(exists == VARIANT_TRUE, "Expected TRUE but got FALSE.\n");
75 VariantClear(&key);
76
77 exists = VARIANT_TRUE;
78 V_VT(&key) = VT_BSTR;
79 V_BSTR(&key) = SysAllocString(key_non_exist);
80 hr = IDictionary_Exists(dict, &key, &exists);
81 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
82 ok(exists == VARIANT_FALSE, "Expected FALSE but got TRUE.\n");
83 VariantClear(&key);
84
85 hr = IDictionary_get_Count(dict, &count);
86 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
87 ok(count == 1, "got %d, expected 1\n", count);
88
89 IDictionary_Release(dict);
90 IDispatch_Release(disp);
91 }
92
93 static void test_comparemode(void)
94 {
95 CompareMethod method;
96 IDictionary *dict;
97 VARIANT key, item;
98 HRESULT hr;
99
100 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
101 &IID_IDictionary, (void**)&dict);
102 ok(hr == S_OK, "got 0x%08x\n", hr);
103
104 if (0) /* crashes on native */
105 {
106 hr = IDictionary_get_CompareMode(dict, NULL);
107 }
108
109 method = 10;
110 hr = IDictionary_get_CompareMode(dict, &method);
111 ok(hr == S_OK, "got 0x%08x\n", hr);
112 ok(method == BinaryCompare, "got %d\n", method);
113
114 /* invalid mode value is not checked */
115 hr = IDictionary_put_CompareMode(dict, 10);
116 ok(hr == S_OK, "got 0x%08x\n", hr);
117
118 hr = IDictionary_get_CompareMode(dict, &method);
119 ok(hr == S_OK, "got 0x%08x\n", hr);
120 ok(method == 10, "got %d\n", method);
121
122 hr = IDictionary_put_CompareMode(dict, DatabaseCompare);
123 ok(hr == S_OK, "got 0x%08x\n", hr);
124
125 hr = IDictionary_get_CompareMode(dict, &method);
126 ok(hr == S_OK, "got 0x%08x\n", hr);
127 ok(method == DatabaseCompare, "got %d\n", method);
128
129 /* try to change mode of a non-empty dict */
130 V_VT(&key) = VT_I2;
131 V_I2(&key) = 0;
132 VariantInit(&item);
133 hr = IDictionary_Add(dict, &key, &item);
134 ok(hr == S_OK, "got 0x%08x\n", hr);
135
136 hr = IDictionary_put_CompareMode(dict, BinaryCompare);
137 ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr);
138
139 IDictionary_Release(dict);
140 }
141
142 static DWORD get_str_hash(const WCHAR *str, CompareMethod method)
143 {
144 DWORD hash = 0;
145
146 while (*str) {
147 WCHAR ch;
148
149 if (method == TextCompare || method == DatabaseCompare)
150 ch = PtrToInt(CharLowerW(IntToPtr(*str)));
151 else
152 ch = *str;
153
154 hash += (hash << 4) + ch;
155 str++;
156 }
157
158 return hash % 1201;
159 }
160
161 static DWORD get_num_hash(FLOAT num)
162 {
163 return (*((DWORD*)&num)) % 1201;
164 }
165
166 static DWORD get_ptr_hash(void *ptr)
167 {
168 return PtrToUlong(ptr) % 1201;
169 }
170
171 typedef union
172 {
173 struct
174 {
175 unsigned int m : 23;
176 unsigned int exp_bias : 8;
177 unsigned int sign : 1;
178 } i;
179 float f;
180 } R4_FIELDS;
181
182 typedef union
183 {
184 struct
185 {
186 unsigned int m_lo : 32; /* 52 bits of precision */
187 unsigned int m_hi : 20;
188 unsigned int exp_bias : 11; /* bias == 1023 */
189 unsigned int sign : 1;
190 } i;
191 double d;
192 } R8_FIELDS;
193
194 static HRESULT WINAPI test_unk_QI(IUnknown *iface, REFIID riid, void **obj)
195 {
196 if (IsEqualIID(riid, &IID_IUnknown)) {
197 *obj = iface;
198 return S_OK;
199 }
200
201 ok(0, "unexpected %s\n", wine_dbgstr_guid(riid));
202 *obj = NULL;
203 return E_NOINTERFACE;
204 }
205
206 static HRESULT WINAPI test_unk_no_QI(IUnknown *iface, REFIID riid, void **obj)
207 {
208 *obj = NULL;
209 return E_NOINTERFACE;
210 }
211
212 static ULONG WINAPI test_unk_AddRef(IUnknown *iface)
213 {
214 ok(0, "unexpected\n");
215 return 2;
216 }
217
218 static ULONG WINAPI test_unk_Release(IUnknown *iface)
219 {
220 return 1;
221 }
222
223 static /* const */ IUnknownVtbl test_unk_vtbl = {
224 test_unk_QI,
225 test_unk_AddRef,
226 test_unk_Release
227 };
228
229 static /* const */ IUnknownVtbl test_unk_no_vtbl = {
230 test_unk_no_QI,
231 test_unk_AddRef,
232 test_unk_Release
233 };
234
235 static HRESULT WINAPI test_disp_QI(IDispatch *iface, REFIID riid, void **obj)
236 {
237 if (IsEqualIID(riid, &IID_IDispatch) || IsEqualIID(riid, &IID_IUnknown)) {
238 *obj = iface;
239 return S_OK;
240 }
241
242 ok(0, "unexpected %s\n", wine_dbgstr_guid(riid));
243 *obj = NULL;
244 return E_NOINTERFACE;
245 }
246
247 static ULONG WINAPI test_disp_AddRef(IDispatch *iface)
248 {
249 ok(0, "unexpected\n");
250 return 2;
251 }
252
253 static ULONG WINAPI test_disp_Release(IDispatch *iface)
254 {
255 return 1;
256 }
257
258 static HRESULT WINAPI test_disp_GetTypeInfoCount(IDispatch *iface, UINT *count)
259 {
260 ok(0, "unexpected call\n");
261 return E_NOTIMPL;
262 }
263
264 static HRESULT WINAPI test_disp_GetTypeInfo(IDispatch *iface, UINT index, LCID lcid, ITypeInfo **ti)
265 {
266 ok(0, "unexpected call\n");
267 return E_NOTIMPL;
268 }
269
270 static HRESULT WINAPI test_disp_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names,
271 UINT name_count, LCID lcid, DISPID *dispid)
272 {
273 ok(0, "unexpected call\n");
274 return E_NOTIMPL;
275 }
276
277 static HRESULT WINAPI test_disp_Invoke(IDispatch *iface, DISPID dispid, REFIID riid,
278 LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *arg_err)
279 {
280 ok(0, "unexpected call\n");
281 return E_NOTIMPL;
282 }
283
284 static /* const */ IDispatchVtbl test_disp_vtbl = {
285 test_disp_QI,
286 test_disp_AddRef,
287 test_disp_Release,
288 test_disp_GetTypeInfoCount,
289 test_disp_GetTypeInfo,
290 test_disp_GetIDsOfNames,
291 test_disp_Invoke
292 };
293
294 static IUnknown test_unk = { &test_unk_vtbl };
295 static IUnknown test_unk2 = { &test_unk_no_vtbl };
296 static IDispatch test_disp = { &test_disp_vtbl };
297
298 static void test_hash_value(void)
299 {
300 /* string test data */
301 static const WCHAR str_hash_tests[][10] = {
302 {'a','b','c','d',0},
303 {'a','B','C','d','1',0},
304 {'1','2','3',0},
305 {'A',0},
306 {'a',0},
307 { 0 }
308 };
309
310 static const int int_hash_tests[] = {
311 0, -1, 100, 1, 255
312 };
313
314 static const FLOAT float_hash_tests[] = {
315 0.0, -1.0, 100.0, 1.0, 255.0, 1.234
316 };
317
318 IDictionary *dict;
319 VARIANT key, hash;
320 IDispatch *disp;
321 DWORD expected;
322 IUnknown *unk;
323 R8_FIELDS fx8;
324 R4_FIELDS fx4;
325 HRESULT hr;
326 unsigned i;
327
328 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
329 &IID_IDictionary, (void**)&dict);
330 ok(hr == S_OK, "got 0x%08x\n", hr);
331
332 V_VT(&key) = VT_BSTR;
333 V_BSTR(&key) = NULL;
334 VariantInit(&hash);
335 hr = IDictionary_get_HashVal(dict, &key, &hash);
336 ok(hr == S_OK, "got 0x%08x\n", hr);
337 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
338 ok(V_I4(&hash) == 0, "got %d\n", V_I4(&hash));
339
340 for (i = 0; i < sizeof(str_hash_tests)/sizeof(str_hash_tests[0]); i++) {
341 expected = get_str_hash(str_hash_tests[i], BinaryCompare);
342
343 hr = IDictionary_put_CompareMode(dict, BinaryCompare);
344 ok(hr == S_OK, "got 0x%08x\n", hr);
345
346 V_VT(&key) = VT_BSTR;
347 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
348 VariantInit(&hash);
349 hr = IDictionary_get_HashVal(dict, &key, &hash);
350 ok(hr == S_OK, "got 0x%08x\n", hr);
351 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
352 ok(V_I4(&hash) == expected, "%d: binary mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
353 expected);
354 VariantClear(&key);
355
356 expected = get_str_hash(str_hash_tests[i], TextCompare);
357 hr = IDictionary_put_CompareMode(dict, TextCompare);
358 ok(hr == S_OK, "got 0x%08x\n", hr);
359
360 V_VT(&key) = VT_BSTR;
361 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
362 VariantInit(&hash);
363 hr = IDictionary_get_HashVal(dict, &key, &hash);
364 ok(hr == S_OK, "got 0x%08x\n", hr);
365 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
366 ok(V_I4(&hash) == expected, "%d: text mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
367 expected);
368 VariantClear(&key);
369
370 expected = get_str_hash(str_hash_tests[i], DatabaseCompare);
371 hr = IDictionary_put_CompareMode(dict, DatabaseCompare);
372 ok(hr == S_OK, "got 0x%08x\n", hr);
373
374 V_VT(&key) = VT_BSTR;
375 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
376 VariantInit(&hash);
377 hr = IDictionary_get_HashVal(dict, &key, &hash);
378 ok(hr == S_OK, "got 0x%08x\n", hr);
379 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
380 ok(V_I4(&hash) == expected, "%d: db mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
381 expected);
382 VariantClear(&key);
383 }
384
385 V_VT(&key) = VT_INT;
386 V_INT(&key) = 1;
387 VariantInit(&hash);
388 hr = IDictionary_get_HashVal(dict, &key, &hash);
389 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
390 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
391 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
392
393 V_VT(&key) = VT_UINT;
394 V_UINT(&key) = 1;
395 VariantInit(&hash);
396 hr = IDictionary_get_HashVal(dict, &key, &hash);
397 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
398 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
399 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
400
401 V_VT(&key) = VT_I1;
402 V_I1(&key) = 1;
403 VariantInit(&hash);
404 hr = IDictionary_get_HashVal(dict, &key, &hash);
405 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
406 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
407 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0xa1), "got hash 0x%08x\n", V_I4(&hash));
408
409 V_VT(&key) = VT_I8;
410 V_I8(&key) = 1;
411 VariantInit(&hash);
412 hr = IDictionary_get_HashVal(dict, &key, &hash);
413 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
414 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
415 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
416
417 V_VT(&key) = VT_UI2;
418 V_UI2(&key) = 1;
419 VariantInit(&hash);
420 hr = IDictionary_get_HashVal(dict, &key, &hash);
421 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
422 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
423 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
424
425 V_VT(&key) = VT_UI4;
426 V_UI4(&key) = 1;
427 VariantInit(&hash);
428 hr = IDictionary_get_HashVal(dict, &key, &hash);
429 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
430 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
431 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
432
433 for (i = 0; i < sizeof(int_hash_tests)/sizeof(int_hash_tests[0]); i++) {
434 SHORT i2;
435 BYTE ui1;
436 LONG i4;
437
438 expected = get_num_hash(int_hash_tests[i]);
439
440 V_VT(&key) = VT_I2;
441 V_I2(&key) = int_hash_tests[i];
442 VariantInit(&hash);
443 hr = IDictionary_get_HashVal(dict, &key, &hash);
444 ok(hr == S_OK, "got 0x%08x\n", hr);
445 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
446 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
447 expected);
448
449 i2 = int_hash_tests[i];
450 V_VT(&key) = VT_I2|VT_BYREF;
451 V_I2REF(&key) = &i2;
452 VariantInit(&hash);
453 hr = IDictionary_get_HashVal(dict, &key, &hash);
454 ok(hr == S_OK, "got 0x%08x\n", hr);
455 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
456 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
457 expected);
458
459 V_VT(&key) = VT_I4;
460 V_I4(&key) = int_hash_tests[i];
461 VariantInit(&hash);
462 hr = IDictionary_get_HashVal(dict, &key, &hash);
463 ok(hr == S_OK, "got 0x%08x\n", hr);
464 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
465 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
466 expected);
467
468 i4 = int_hash_tests[i];
469 V_VT(&key) = VT_I4|VT_BYREF;
470 V_I4REF(&key) = &i4;
471 VariantInit(&hash);
472 hr = IDictionary_get_HashVal(dict, &key, &hash);
473 ok(hr == S_OK, "got 0x%08x\n", hr);
474 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
475 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
476 expected);
477
478 expected = get_num_hash((FLOAT)(BYTE)int_hash_tests[i]);
479 V_VT(&key) = VT_UI1;
480 V_UI1(&key) = int_hash_tests[i];
481 VariantInit(&hash);
482 hr = IDictionary_get_HashVal(dict, &key, &hash);
483 ok(hr == S_OK, "got 0x%08x\n", hr);
484 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
485 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
486 expected);
487
488 ui1 = int_hash_tests[i];
489 V_VT(&key) = VT_UI1|VT_BYREF;
490 V_UI1REF(&key) = &ui1;
491 VariantInit(&hash);
492 hr = IDictionary_get_HashVal(dict, &key, &hash);
493 ok(hr == S_OK, "got 0x%08x\n", hr);
494 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
495 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
496 expected);
497 }
498
499 /* nan */
500 fx4.f = 10.0;
501 fx4.i.exp_bias = 0xff;
502
503 V_VT(&key) = VT_R4;
504 V_R4(&key) = fx4.f;
505 VariantInit(&hash);
506 hr = IDictionary_get_HashVal(dict, &key, &hash);
507 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
508 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
509 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ ||
510 V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash));
511
512 /* inf */
513 fx4.f = 10.0;
514 fx4.i.m = 0;
515 fx4.i.exp_bias = 0xff;
516
517 V_VT(&key) = VT_R4;
518 V_R4(&key) = fx4.f;
519 V_I4(&hash) = 10;
520 hr = IDictionary_get_HashVal(dict, &key, &hash);
521 ok(hr == S_OK, "got 0x%08x\n", hr);
522 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
523 ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash));
524
525 /* nan */
526 fx8.d = 10.0;
527 fx8.i.exp_bias = 0x7ff;
528
529 V_VT(&key) = VT_R8;
530 V_R8(&key) = fx8.d;
531 VariantInit(&hash);
532 hr = IDictionary_get_HashVal(dict, &key, &hash);
533 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
534 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
535 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ ||
536 V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash));
537
538 V_VT(&key) = VT_DATE;
539 V_DATE(&key) = fx8.d;
540 VariantInit(&hash);
541 hr = IDictionary_get_HashVal(dict, &key, &hash);
542 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
543 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
544 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ ||
545 V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash));
546
547 /* inf */
548 fx8.d = 10.0;
549 fx8.i.m_lo = 0;
550 fx8.i.m_hi = 0;
551 fx8.i.exp_bias = 0x7ff;
552
553 V_VT(&key) = VT_R8;
554 V_R8(&key) = fx8.d;
555 V_I4(&hash) = 10;
556 hr = IDictionary_get_HashVal(dict, &key, &hash);
557 ok(hr == S_OK, "got 0x%08x\n", hr);
558 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
559 ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash));
560
561 V_VT(&key) = VT_DATE;
562 V_DATE(&key) = fx8.d;
563 V_I4(&hash) = 10;
564 hr = IDictionary_get_HashVal(dict, &key, &hash);
565 ok(hr == S_OK, "got 0x%08x\n", hr);
566 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
567 ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash));
568
569 for (i = 0; i < sizeof(float_hash_tests)/sizeof(float_hash_tests[0]); i++) {
570 double dbl;
571 FLOAT flt;
572 DATE date;
573
574 expected = get_num_hash(float_hash_tests[i]);
575
576 V_VT(&key) = VT_R4;
577 V_R4(&key) = float_hash_tests[i];
578 VariantInit(&hash);
579 hr = IDictionary_get_HashVal(dict, &key, &hash);
580 ok(hr == S_OK, "got 0x%08x\n", hr);
581 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
582 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
583 expected);
584
585 flt = float_hash_tests[i];
586 V_VT(&key) = VT_R4|VT_BYREF;
587 V_R4REF(&key) = &flt;
588 VariantInit(&hash);
589 hr = IDictionary_get_HashVal(dict, &key, &hash);
590 ok(hr == S_OK, "got 0x%08x\n", hr);
591 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
592 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
593 expected);
594
595 V_VT(&key) = VT_R8;
596 V_R8(&key) = float_hash_tests[i];
597 VariantInit(&hash);
598 hr = IDictionary_get_HashVal(dict, &key, &hash);
599 ok(hr == S_OK, "got 0x%08x\n", hr);
600 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
601 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
602 expected);
603
604 dbl = float_hash_tests[i];
605 V_VT(&key) = VT_R8|VT_BYREF;
606 V_R8REF(&key) = &dbl;
607 VariantInit(&hash);
608 hr = IDictionary_get_HashVal(dict, &key, &hash);
609 ok(hr == S_OK, "got 0x%08x\n", hr);
610 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
611 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
612 expected);
613
614 V_VT(&key) = VT_DATE;
615 V_DATE(&key) = float_hash_tests[i];
616 VariantInit(&hash);
617 hr = IDictionary_get_HashVal(dict, &key, &hash);
618 ok(hr == S_OK, "got 0x%08x\n", hr);
619 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
620 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
621 expected);
622
623 V_VT(&key) = VT_DATE|VT_BYREF;
624 date = float_hash_tests[i];
625 V_DATEREF(&key) = &date;
626 VariantInit(&hash);
627 hr = IDictionary_get_HashVal(dict, &key, &hash);
628 ok(hr == S_OK, "got 0x%08x\n", hr);
629 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
630 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
631 expected);
632 }
633
634 /* interface pointers as keys */
635 V_VT(&key) = VT_UNKNOWN;
636 V_UNKNOWN(&key) = 0;
637 VariantInit(&hash);
638 V_I4(&hash) = 1;
639 hr = IDictionary_get_HashVal(dict, &key, &hash);
640 ok(hr == S_OK, "got 0x%08x\n", hr);
641 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
642 ok(V_I4(&hash) == 0, "got hash 0x%08x, expected 0\n", V_I4(&hash));
643
644 /* QI doesn't work */
645 V_VT(&key) = VT_UNKNOWN;
646 V_UNKNOWN(&key) = &test_unk2;
647 VariantInit(&hash);
648 expected = get_ptr_hash(&test_unk2);
649 hr = IDictionary_get_HashVal(dict, &key, &hash);
650 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k */, "got 0x%08x\n", hr);
651 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
652 ok(V_I4(&hash) == ~0u, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
653
654 V_VT(&key) = VT_UNKNOWN;
655 V_UNKNOWN(&key) = &test_unk;
656 VariantInit(&hash);
657 expected = get_ptr_hash(&test_unk);
658 hr = IDictionary_get_HashVal(dict, &key, &hash);
659 ok(hr == S_OK, "got 0x%08x\n", hr);
660 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
661 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
662
663 /* interface without IDispatch support */
664 V_VT(&key) = VT_DISPATCH;
665 V_DISPATCH(&key) = (IDispatch*)&test_unk;
666 VariantInit(&hash);
667 expected = get_ptr_hash(&test_unk);
668 hr = IDictionary_get_HashVal(dict, &key, &hash);
669 ok(hr == S_OK, "got 0x%08x\n", hr);
670 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
671 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
672
673 V_VT(&key) = VT_DISPATCH;
674 V_DISPATCH(&key) = &test_disp;
675 VariantInit(&hash);
676 expected = get_ptr_hash(&test_disp);
677 hr = IDictionary_get_HashVal(dict, &key, &hash);
678 ok(hr == S_OK, "got 0x%08x\n", hr);
679 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
680 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
681
682 /* same with BYREF */
683 if (0) { /* crashes on native */
684 V_VT(&key) = VT_UNKNOWN|VT_BYREF;
685 V_UNKNOWNREF(&key) = 0;
686 hr = IDictionary_get_HashVal(dict, &key, &hash);
687 }
688 unk = NULL;
689 V_VT(&key) = VT_UNKNOWN|VT_BYREF;
690 V_UNKNOWNREF(&key) = &unk;
691 VariantInit(&hash);
692 V_I4(&hash) = 1;
693 hr = IDictionary_get_HashVal(dict, &key, &hash);
694 ok(hr == S_OK, "got 0x%08x\n", hr);
695 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
696 ok(V_I4(&hash) == 0, "got hash 0x%08x, expected 0\n", V_I4(&hash));
697
698 V_VT(&key) = VT_UNKNOWN|VT_BYREF;
699 unk = &test_unk;
700 V_UNKNOWNREF(&key) = &unk;
701 VariantInit(&hash);
702 expected = get_ptr_hash(&test_unk);
703 hr = IDictionary_get_HashVal(dict, &key, &hash);
704 ok(hr == S_OK, "got 0x%08x\n", hr);
705 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
706 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
707
708 /* interface without IDispatch support */
709 V_VT(&key) = VT_DISPATCH|VT_BYREF;
710 unk = &test_unk;
711 V_DISPATCHREF(&key) = (IDispatch**)&unk;
712 VariantInit(&hash);
713 expected = get_ptr_hash(&test_unk);
714 hr = IDictionary_get_HashVal(dict, &key, &hash);
715 ok(hr == S_OK, "got 0x%08x\n", hr);
716 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
717 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
718
719 V_VT(&key) = VT_DISPATCH|VT_BYREF;
720 disp = &test_disp;
721 V_DISPATCHREF(&key) = &disp;
722 VariantInit(&hash);
723 expected = get_ptr_hash(&test_disp);
724 hr = IDictionary_get_HashVal(dict, &key, &hash);
725 ok(hr == S_OK, "got 0x%08x\n", hr);
726 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
727 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
728
729 IDictionary_Release(dict);
730 }
731
732 static void test_Exists(void)
733 {
734 VARIANT_BOOL exists;
735 IDictionary *dict;
736 VARIANT key, item;
737 HRESULT hr;
738
739 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
740 &IID_IDictionary, (void**)&dict);
741 ok(hr == S_OK, "got 0x%08x\n", hr);
742
743 if (0) /* crashes on native */
744 hr = IDictionary_Exists(dict, NULL, NULL);
745
746 V_VT(&key) = VT_I2;
747 V_I2(&key) = 0;
748 hr = IDictionary_Exists(dict, &key, NULL);
749 ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr);
750
751 V_VT(&key) = VT_I2;
752 V_I2(&key) = 0;
753 exists = VARIANT_TRUE;
754 hr = IDictionary_Exists(dict, &key, &exists);
755 ok(hr == S_OK, "got 0x%08x\n", hr);
756 ok(exists == VARIANT_FALSE, "got %x\n", exists);
757
758 VariantInit(&item);
759 hr = IDictionary_Add(dict, &key, &item);
760 ok(hr == S_OK, "got 0x%08x\n", hr);
761
762 V_VT(&key) = VT_R4;
763 V_R4(&key) = 0.0;
764 hr = IDictionary_Add(dict, &key, &item);
765 ok(hr == CTL_E_KEY_ALREADY_EXISTS, "got 0x%08x\n", hr);
766
767 V_VT(&key) = VT_I2;
768 V_I2(&key) = 0;
769 hr = IDictionary_Exists(dict, &key, NULL);
770 ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr);
771
772 V_VT(&key) = VT_I2;
773 V_I2(&key) = 0;
774 exists = VARIANT_FALSE;
775 hr = IDictionary_Exists(dict, &key, &exists);
776 ok(hr == S_OK, "got 0x%08x\n", hr);
777 ok(exists == VARIANT_TRUE, "got %x\n", exists);
778
779 /* key of different type, but resolves to same hash value */
780 V_VT(&key) = VT_R4;
781 V_R4(&key) = 0.0;
782 exists = VARIANT_FALSE;
783 hr = IDictionary_Exists(dict, &key, &exists);
784 ok(hr == S_OK, "got 0x%08x\n", hr);
785 ok(exists == VARIANT_TRUE, "got %x\n", exists);
786
787 IDictionary_Release(dict);
788 }
789
790 static void test_Keys(void)
791 {
792 VARIANT key, keys, item;
793 IDictionary *dict;
794 LONG index;
795 HRESULT hr;
796
797 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
798 &IID_IDictionary, (void**)&dict);
799 ok(hr == S_OK, "got 0x%08x\n", hr);
800
801 hr = IDictionary_Keys(dict, NULL);
802 ok(hr == S_OK, "got 0x%08x\n", hr);
803
804 VariantInit(&keys);
805 hr = IDictionary_Keys(dict, &keys);
806 ok(hr == S_OK, "got 0x%08x\n", hr);
807 ok(V_VT(&keys) == (VT_ARRAY|VT_VARIANT), "got %d\n", V_VT(&keys));
808 VariantClear(&keys);
809
810 V_VT(&key) = VT_R4;
811 V_R4(&key) = 0.0;
812 VariantInit(&item);
813 hr = IDictionary_Add(dict, &key, &item);
814 ok(hr == S_OK, "got 0x%08x\n", hr);
815
816 VariantInit(&keys);
817 hr = IDictionary_Keys(dict, &keys);
818 ok(hr == S_OK, "got 0x%08x\n", hr);
819 ok(V_VT(&keys) == (VT_ARRAY|VT_VARIANT), "got %d\n", V_VT(&keys));
820
821 VariantInit(&key);
822 index = 0;
823 hr = SafeArrayGetElement(V_ARRAY(&keys), &index, &key);
824 ok(hr == S_OK, "got 0x%08x\n", hr);
825 ok(V_VT(&key) == VT_R4, "got %d\n", V_VT(&key));
826
827 index = SafeArrayGetDim(V_ARRAY(&keys));
828 ok(index == 1, "got %d\n", index);
829
830 hr = SafeArrayGetUBound(V_ARRAY(&keys), 1, &index);
831 ok(hr == S_OK, "got 0x%08x\n", hr);
832 ok(index == 0, "got %d\n", index);
833
834 VariantClear(&keys);
835
836 IDictionary_Release(dict);
837 }
838
839 static void test_Remove(void)
840 {
841 VARIANT key, item;
842 IDictionary *dict;
843 HRESULT hr;
844
845 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
846 &IID_IDictionary, (void**)&dict);
847 ok(hr == S_OK, "got 0x%08x\n", hr);
848
849 if (0)
850 hr = IDictionary_Remove(dict, NULL);
851
852 /* nothing added yet */
853 V_VT(&key) = VT_R4;
854 V_R4(&key) = 0.0;
855 hr = IDictionary_Remove(dict, &key);
856 ok(hr == CTL_E_ELEMENT_NOT_FOUND, "got 0x%08x\n", hr);
857
858 VariantInit(&item);
859 hr = IDictionary_Add(dict, &key, &item);
860 ok(hr == S_OK, "got 0x%08x\n", hr);
861
862 hr = IDictionary_Remove(dict, &key);
863 ok(hr == S_OK, "got 0x%08x\n", hr);
864
865 IDictionary_Release(dict);
866 }
867
868 static void test_Item(void)
869 {
870 VARIANT key, item;
871 IDictionary *dict;
872 HRESULT hr;
873
874 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
875 &IID_IDictionary, (void**)&dict);
876 ok(hr == S_OK, "got 0x%08x\n", hr);
877
878 V_VT(&key) = VT_I2;
879 V_I2(&key) = 10;
880 V_VT(&item) = VT_I2;
881 V_I2(&item) = 123;
882 hr = IDictionary_get_Item(dict, &key, &item);
883 ok(hr == S_OK, "got 0x%08x\n", hr);
884 ok(V_VT(&item) == VT_EMPTY, "got %d\n", V_VT(&item));
885
886 V_VT(&key) = VT_I2;
887 V_I2(&key) = 10;
888 V_VT(&item) = VT_I2;
889 hr = IDictionary_get_Item(dict, &key, &item);
890 ok(hr == S_OK, "got 0x%08x\n", hr);
891 ok(V_VT(&item) == VT_EMPTY, "got %d\n", V_VT(&item));
892
893 IDictionary_Release(dict);
894 }
895
896 static void test_Add(void)
897 {
898 static const WCHAR testW[] = {'t','e','s','t','W',0};
899 VARIANT key, item;
900 IDictionary *dict;
901 HRESULT hr;
902 BSTR str;
903
904 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
905 &IID_IDictionary, (void**)&dict);
906 ok(hr == S_OK, "got 0x%08x\n", hr);
907
908 str = SysAllocString(testW);
909 V_VT(&key) = VT_I2;
910 V_I2(&key) = 1;
911 V_VT(&item) = VT_BSTR|VT_BYREF;
912 V_BSTRREF(&item) = &str;
913 hr = IDictionary_Add(dict, &key, &item);
914 ok(hr == S_OK, "got 0x%08x\n", hr);
915
916 hr = IDictionary_get_Item(dict, &key, &item);
917 ok(hr == S_OK, "got 0x%08x\n", hr);
918 ok(V_VT(&item) == VT_BSTR, "got %d\n", V_VT(&item));
919
920 SysFreeString(str);
921
922 IDictionary_Release(dict);
923 }
924
925 static void test_IEnumVARIANT(void)
926 {
927 IUnknown *enum1, *enum2;
928 IEnumVARIANT *enumvar;
929 VARIANT key, item;
930 IDictionary *dict;
931 ULONG fetched;
932 HRESULT hr;
933
934 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
935 &IID_IDictionary, (void**)&dict);
936 ok(hr == S_OK, "got 0x%08x\n", hr);
937
938 if (0) /* crashes on native */
939 {
940 hr = IDictionary__NewEnum(dict, NULL);
941 }
942
943 hr = IDictionary__NewEnum(dict, &enum1);
944 ok(hr == S_OK, "got 0x%08x\n", hr);
945
946 hr = IDictionary__NewEnum(dict, &enum2);
947 ok(hr == S_OK, "got 0x%08x\n", hr);
948 ok(enum1 != enum2, "got %p, %p\n", enum2, enum1);
949 IUnknown_Release(enum2);
950
951 hr = IUnknown_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enumvar);
952 ok(hr == S_OK, "got 0x%08x\n", hr);
953 IUnknown_Release(enum1);
954
955 /* dictionary is empty */
956 hr = IEnumVARIANT_Skip(enumvar, 1);
957 ok(hr == S_FALSE, "got 0x%08x\n", hr);
958
959 hr = IEnumVARIANT_Skip(enumvar, 0);
960 ok(hr == S_OK, "got 0x%08x\n", hr);
961
962 V_VT(&key) = VT_I2;
963 V_I2(&key) = 1;
964 V_VT(&item) = VT_I4;
965 V_I4(&item) = 100;
966 hr = IDictionary_Add(dict, &key, &item);
967 ok(hr == S_OK, "got 0x%08x\n", hr);
968
969 hr = IEnumVARIANT_Skip(enumvar, 0);
970 ok(hr == S_OK, "got 0x%08x\n", hr);
971
972 hr = IEnumVARIANT_Reset(enumvar);
973 ok(hr == S_OK, "got 0x%08x\n", hr);
974 hr = IEnumVARIANT_Skip(enumvar, 1);
975 ok(hr == S_OK, "got 0x%08x\n", hr);
976 hr = IEnumVARIANT_Skip(enumvar, 1);
977 ok(hr == S_FALSE, "got 0x%08x\n", hr);
978
979 V_VT(&key) = VT_I2;
980 V_I2(&key) = 4000;
981 V_VT(&item) = VT_I4;
982 V_I4(&item) = 200;
983 hr = IDictionary_Add(dict, &key, &item);
984 ok(hr == S_OK, "got 0x%08x\n", hr);
985
986 V_VT(&key) = VT_I2;
987 V_I2(&key) = 0;
988 V_VT(&item) = VT_I4;
989 V_I4(&item) = 300;
990 hr = IDictionary_Add(dict, &key, &item);
991 ok(hr == S_OK, "got 0x%08x\n", hr);
992
993 hr = IEnumVARIANT_Reset(enumvar);
994 ok(hr == S_OK, "got 0x%08x\n", hr);
995
996 VariantInit(&key);
997 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
998 ok(hr == S_OK, "got 0x%08x\n", hr);
999 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
1000 ok(V_I2(&key) == 1, "got %d\n", V_I2(&key));
1001 ok(fetched == 1, "got %u\n", fetched);
1002
1003 hr = IEnumVARIANT_Reset(enumvar);
1004 ok(hr == S_OK, "got 0x%08x\n", hr);
1005
1006 hr = IDictionary_Remove(dict, &key);
1007 ok(hr == S_OK, "got 0x%08x\n", hr);
1008
1009 VariantInit(&key);
1010 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1011 ok(hr == S_OK, "got 0x%08x\n", hr);
1012 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
1013 ok(V_I2(&key) == 4000, "got %d\n", V_I2(&key));
1014 ok(fetched == 1, "got %u\n", fetched);
1015
1016 VariantInit(&key);
1017 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1018 ok(hr == S_OK, "got 0x%08x\n", hr);
1019 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
1020 ok(V_I2(&key) == 0, "got %d\n", V_I2(&key));
1021 ok(fetched == 1, "got %u\n", fetched);
1022
1023 /* enumeration reached the bottom, add one more pair */
1024 VariantInit(&key);
1025 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1026 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1027
1028 V_VT(&key) = VT_I2;
1029 V_I2(&key) = 13;
1030 V_VT(&item) = VT_I4;
1031 V_I4(&item) = 350;
1032 hr = IDictionary_Add(dict, &key, &item);
1033 ok(hr == S_OK, "got 0x%08x\n", hr);
1034
1035 /* still doesn't work until Reset() */
1036 VariantInit(&key);
1037 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1038 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1039
1040 IEnumVARIANT_Release(enumvar);
1041 IDictionary_Release(dict);
1042 }
1043
1044 START_TEST(dictionary)
1045 {
1046 IDispatch *disp;
1047 HRESULT hr;
1048
1049 CoInitialize(NULL);
1050
1051 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1052 &IID_IDispatch, (void**)&disp);
1053 if(FAILED(hr)) {
1054 win_skip("Dictionary object is not supported: %08x\n", hr);
1055 CoUninitialize();
1056 return;
1057 }
1058 IDispatch_Release(disp);
1059
1060 test_interfaces();
1061 test_comparemode();
1062 test_hash_value();
1063 test_Exists();
1064 test_Keys();
1065 test_Remove();
1066 test_Item();
1067 test_Add();
1068 test_IEnumVARIANT();
1069
1070 CoUninitialize();
1071 }