wined3d: Pass a wined3d_device_context to wined3d_cs_emit_blt_sub_resource().
[wine/zf.git] / dlls / scrrun / tests / dictionary.c
blob4259bc71c8e3f90227128c8469d36839f3ff8340
1 /*
2 * Copyright (C) 2012 Alistair Leslie-Hughes
3 * Copyright 2015 Nikolay Sivov for CodeWeavers
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 #define COBJMACROS
21 #include <stdio.h>
23 #include "windows.h"
24 #include "ole2.h"
25 #include "oleauto.h"
26 #include "olectl.h"
27 #include "dispex.h"
29 #include "wine/test.h"
31 #include "scrrun.h"
33 #define test_provideclassinfo(a, b) _test_provideclassinfo((IDispatch*)a, b, __LINE__)
34 static void _test_provideclassinfo(IDispatch *disp, const GUID *guid, int line)
36 IProvideClassInfo *classinfo;
37 TYPEATTR *attr;
38 ITypeInfo *ti;
39 IUnknown *unk;
40 HRESULT hr;
42 hr = IDispatch_QueryInterface(disp, &IID_IProvideClassInfo, (void **)&classinfo);
43 ok_(__FILE__,line) (hr == S_OK, "Failed to get IProvideClassInfo, %#x.\n", hr);
45 hr = IProvideClassInfo_GetClassInfo(classinfo, &ti);
46 ok_(__FILE__,line) (hr == S_OK, "GetClassInfo() failed, %#x.\n", hr);
48 hr = ITypeInfo_GetTypeAttr(ti, &attr);
49 ok_(__FILE__,line) (hr == S_OK, "GetTypeAttr() failed, %#x.\n", hr);
51 ok_(__FILE__,line) (IsEqualGUID(&attr->guid, guid), "Unexpected typeinfo %s, expected %s\n", wine_dbgstr_guid(&attr->guid),
52 wine_dbgstr_guid(guid));
54 hr = IProvideClassInfo_QueryInterface(classinfo, &IID_IUnknown, (void **)&unk);
55 ok(hr == S_OK, "Failed to QI for IUnknown.\n");
56 ok(unk == (IUnknown *)disp, "Got unk %p, original %p\n", unk, disp);
57 IUnknown_Release(unk);
59 IProvideClassInfo_Release(classinfo);
60 ITypeInfo_ReleaseTypeAttr(ti, attr);
61 ITypeInfo_Release(ti);
64 static void test_interfaces(void)
66 HRESULT hr;
67 IDispatch *disp;
68 IDispatchEx *dispex;
69 IDictionary *dict;
70 IObjectWithSite *site;
71 VARIANT key, value;
72 VARIANT_BOOL exists;
73 LONG count = 0;
75 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
76 &IID_IDispatch, (void**)&disp);
77 ok(hr == S_OK, "got 0x%08x\n", hr);
79 VariantInit(&key);
80 VariantInit(&value);
82 hr = IDispatch_QueryInterface(disp, &IID_IDictionary, (void**)&dict);
83 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
85 hr = IDispatch_QueryInterface(disp, &IID_IObjectWithSite, (void**)&site);
86 ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE);
88 hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
89 ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE);
91 test_provideclassinfo(disp, &CLSID_Dictionary);
93 V_VT(&key) = VT_BSTR;
94 V_BSTR(&key) = SysAllocString(L"a");
95 V_VT(&value) = VT_BSTR;
96 V_BSTR(&value) = SysAllocString(L"a");
97 hr = IDictionary_Add(dict, &key, &value);
98 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
99 VariantClear(&value);
101 exists = VARIANT_FALSE;
102 hr = IDictionary_Exists(dict, &key, &exists);
103 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
104 ok(exists == VARIANT_TRUE, "Expected TRUE but got FALSE.\n");
105 VariantClear(&key);
107 exists = VARIANT_TRUE;
108 V_VT(&key) = VT_BSTR;
109 V_BSTR(&key) = SysAllocString(L"b");
110 hr = IDictionary_Exists(dict, &key, &exists);
111 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
112 ok(exists == VARIANT_FALSE, "Expected FALSE but got TRUE.\n");
113 VariantClear(&key);
115 hr = IDictionary_get_Count(dict, &count);
116 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
117 ok(count == 1, "got %d, expected 1\n", count);
119 IDictionary_Release(dict);
120 IDispatch_Release(disp);
123 static void test_comparemode(void)
125 CompareMethod method;
126 IDictionary *dict;
127 VARIANT key, item;
128 HRESULT hr;
130 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
131 &IID_IDictionary, (void**)&dict);
132 ok(hr == S_OK, "got 0x%08x\n", hr);
134 if (0) /* crashes on native */
135 hr = IDictionary_get_CompareMode(dict, NULL);
137 method = 10;
138 hr = IDictionary_get_CompareMode(dict, &method);
139 ok(hr == S_OK, "got 0x%08x\n", hr);
140 ok(method == BinaryCompare, "got %d\n", method);
142 /* invalid mode value is not checked */
143 hr = IDictionary_put_CompareMode(dict, 10);
144 ok(hr == S_OK, "got 0x%08x\n", hr);
146 hr = IDictionary_get_CompareMode(dict, &method);
147 ok(hr == S_OK, "got 0x%08x\n", hr);
148 ok(method == 10, "got %d\n", method);
150 hr = IDictionary_put_CompareMode(dict, DatabaseCompare);
151 ok(hr == S_OK, "got 0x%08x\n", hr);
153 hr = IDictionary_get_CompareMode(dict, &method);
154 ok(hr == S_OK, "got 0x%08x\n", hr);
155 ok(method == DatabaseCompare, "got %d\n", method);
157 /* try to change mode of a non-empty dict */
158 V_VT(&key) = VT_I2;
159 V_I2(&key) = 0;
160 VariantInit(&item);
161 hr = IDictionary_Add(dict, &key, &item);
162 ok(hr == S_OK, "got 0x%08x\n", hr);
164 hr = IDictionary_put_CompareMode(dict, BinaryCompare);
165 ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr);
167 IDictionary_Release(dict);
170 static DWORD get_str_hash(const WCHAR *str, CompareMethod method)
172 DWORD hash = 0;
174 while (*str) {
175 WCHAR ch;
177 if (method == TextCompare || method == DatabaseCompare)
178 ch = PtrToInt(CharLowerW(IntToPtr(*str)));
179 else
180 ch = *str;
182 hash += (hash << 4) + ch;
183 str++;
186 return hash % 1201;
189 static DWORD get_num_hash(FLOAT num)
191 return (*((DWORD*)&num)) % 1201;
194 static DWORD get_ptr_hash(void *ptr)
196 return PtrToUlong(ptr) % 1201;
199 typedef union
201 struct
203 unsigned int m : 23;
204 unsigned int exp_bias : 8;
205 unsigned int sign : 1;
206 } i;
207 float f;
208 } R4_FIELDS;
210 typedef union
212 struct
214 unsigned int m_lo : 32; /* 52 bits of precision */
215 unsigned int m_hi : 20;
216 unsigned int exp_bias : 11; /* bias == 1023 */
217 unsigned int sign : 1;
218 } i;
219 double d;
220 } R8_FIELDS;
222 static HRESULT WINAPI test_unk_QI(IUnknown *iface, REFIID riid, void **obj)
224 if (IsEqualIID(riid, &IID_IUnknown)) {
225 *obj = iface;
226 return S_OK;
229 ok(0, "unexpected %s\n", wine_dbgstr_guid(riid));
230 *obj = NULL;
231 return E_NOINTERFACE;
234 static HRESULT WINAPI test_unk_no_QI(IUnknown *iface, REFIID riid, void **obj)
236 *obj = NULL;
237 return E_NOINTERFACE;
240 static ULONG WINAPI test_unk_AddRef(IUnknown *iface)
242 ok(0, "unexpected\n");
243 return 2;
246 static ULONG WINAPI test_unk_Release(IUnknown *iface)
248 return 1;
251 static const IUnknownVtbl test_unk_vtbl = {
252 test_unk_QI,
253 test_unk_AddRef,
254 test_unk_Release
257 static const IUnknownVtbl test_unk_no_vtbl = {
258 test_unk_no_QI,
259 test_unk_AddRef,
260 test_unk_Release
263 static HRESULT WINAPI test_disp_QI(IDispatch *iface, REFIID riid, void **obj)
265 if (IsEqualIID(riid, &IID_IDispatch) || IsEqualIID(riid, &IID_IUnknown)) {
266 *obj = iface;
267 return S_OK;
270 ok(0, "unexpected %s\n", wine_dbgstr_guid(riid));
271 *obj = NULL;
272 return E_NOINTERFACE;
275 static ULONG WINAPI test_disp_AddRef(IDispatch *iface)
277 ok(0, "unexpected\n");
278 return 2;
281 static ULONG WINAPI test_disp_Release(IDispatch *iface)
283 return 1;
286 static HRESULT WINAPI test_disp_GetTypeInfoCount(IDispatch *iface, UINT *count)
288 ok(0, "unexpected call\n");
289 return E_NOTIMPL;
292 static HRESULT WINAPI test_disp_GetTypeInfo(IDispatch *iface, UINT index, LCID lcid, ITypeInfo **ti)
294 ok(0, "unexpected call\n");
295 return E_NOTIMPL;
298 static HRESULT WINAPI test_disp_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names,
299 UINT name_count, LCID lcid, DISPID *dispid)
301 ok(0, "unexpected call\n");
302 return E_NOTIMPL;
305 static HRESULT WINAPI test_disp_Invoke(IDispatch *iface, DISPID dispid, REFIID riid,
306 LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *arg_err)
308 ok(0, "unexpected call\n");
309 return E_NOTIMPL;
312 static const IDispatchVtbl test_disp_vtbl = {
313 test_disp_QI,
314 test_disp_AddRef,
315 test_disp_Release,
316 test_disp_GetTypeInfoCount,
317 test_disp_GetTypeInfo,
318 test_disp_GetIDsOfNames,
319 test_disp_Invoke
322 static IUnknown test_unk = { &test_unk_vtbl };
323 static IUnknown test_unk2 = { &test_unk_no_vtbl };
324 static IDispatch test_disp = { &test_disp_vtbl };
326 static void test_hash_value(void)
328 /* string test data */
329 static const WCHAR str_hash_tests[][10] =
331 L"abcd",
332 L"aBCd1",
333 L"123",
334 L"A",
335 L"a",
339 static const int int_hash_tests[] = {
340 0, -1, 100, 1, 255
343 static const FLOAT float_hash_tests[] = {
344 0.0, -1.0, 100.0, 1.0, 255.0, 1.234
347 IDictionary *dict;
348 VARIANT key, hash;
349 IDispatch *disp;
350 DWORD expected;
351 IUnknown *unk;
352 R8_FIELDS fx8;
353 R4_FIELDS fx4;
354 HRESULT hr;
355 unsigned i;
357 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
358 &IID_IDictionary, (void**)&dict);
359 ok(hr == S_OK, "got 0x%08x\n", hr);
361 V_VT(&key) = VT_BSTR;
362 V_BSTR(&key) = NULL;
363 VariantInit(&hash);
364 hr = IDictionary_get_HashVal(dict, &key, &hash);
365 ok(hr == S_OK, "got 0x%08x\n", hr);
366 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
367 ok(V_I4(&hash) == 0, "got %d\n", V_I4(&hash));
369 for (i = 0; i < ARRAY_SIZE(str_hash_tests); i++) {
370 expected = get_str_hash(str_hash_tests[i], BinaryCompare);
372 hr = IDictionary_put_CompareMode(dict, BinaryCompare);
373 ok(hr == S_OK, "got 0x%08x\n", hr);
375 V_VT(&key) = VT_BSTR;
376 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
377 VariantInit(&hash);
378 hr = IDictionary_get_HashVal(dict, &key, &hash);
379 ok(hr == S_OK, "got 0x%08x\n", hr);
380 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
381 ok(V_I4(&hash) == expected, "%d: binary mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
382 expected);
383 VariantClear(&key);
385 expected = get_str_hash(str_hash_tests[i], TextCompare);
386 hr = IDictionary_put_CompareMode(dict, TextCompare);
387 ok(hr == S_OK, "got 0x%08x\n", hr);
389 V_VT(&key) = VT_BSTR;
390 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
391 VariantInit(&hash);
392 hr = IDictionary_get_HashVal(dict, &key, &hash);
393 ok(hr == S_OK, "got 0x%08x\n", hr);
394 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
395 ok(V_I4(&hash) == expected, "%d: text mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
396 expected);
397 VariantClear(&key);
399 expected = get_str_hash(str_hash_tests[i], DatabaseCompare);
400 hr = IDictionary_put_CompareMode(dict, DatabaseCompare);
401 ok(hr == S_OK, "got 0x%08x\n", hr);
403 V_VT(&key) = VT_BSTR;
404 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
405 VariantInit(&hash);
406 hr = IDictionary_get_HashVal(dict, &key, &hash);
407 ok(hr == S_OK, "got 0x%08x\n", hr);
408 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
409 ok(V_I4(&hash) == expected, "%d: db mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
410 expected);
411 VariantClear(&key);
414 V_VT(&key) = VT_INT;
415 V_INT(&key) = 1;
416 VariantInit(&hash);
417 hr = IDictionary_get_HashVal(dict, &key, &hash);
418 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
419 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
420 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
422 V_VT(&key) = VT_UINT;
423 V_UINT(&key) = 1;
424 VariantInit(&hash);
425 hr = IDictionary_get_HashVal(dict, &key, &hash);
426 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
427 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
428 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
430 V_VT(&key) = VT_I1;
431 V_I1(&key) = 1;
432 VariantInit(&hash);
433 hr = IDictionary_get_HashVal(dict, &key, &hash);
434 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
435 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
436 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0xa1), "got hash 0x%08x\n", V_I4(&hash));
438 V_VT(&key) = VT_I8;
439 V_I8(&key) = 1;
440 VariantInit(&hash);
441 hr = IDictionary_get_HashVal(dict, &key, &hash);
442 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
443 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
444 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
446 V_VT(&key) = VT_UI2;
447 V_UI2(&key) = 1;
448 VariantInit(&hash);
449 hr = IDictionary_get_HashVal(dict, &key, &hash);
450 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
451 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
452 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
454 V_VT(&key) = VT_UI4;
455 V_UI4(&key) = 1;
456 VariantInit(&hash);
457 hr = IDictionary_get_HashVal(dict, &key, &hash);
458 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
459 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
460 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
462 for (i = 0; i < ARRAY_SIZE(int_hash_tests); i++) {
463 SHORT i2;
464 BYTE ui1;
465 LONG i4;
467 expected = get_num_hash(int_hash_tests[i]);
469 V_VT(&key) = VT_I2;
470 V_I2(&key) = int_hash_tests[i];
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);
478 i2 = int_hash_tests[i];
479 V_VT(&key) = VT_I2|VT_BYREF;
480 V_I2REF(&key) = &i2;
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);
488 V_VT(&key) = VT_I4;
489 V_I4(&key) = int_hash_tests[i];
490 VariantInit(&hash);
491 hr = IDictionary_get_HashVal(dict, &key, &hash);
492 ok(hr == S_OK, "got 0x%08x\n", hr);
493 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
494 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
495 expected);
497 i4 = int_hash_tests[i];
498 V_VT(&key) = VT_I4|VT_BYREF;
499 V_I4REF(&key) = &i4;
500 VariantInit(&hash);
501 hr = IDictionary_get_HashVal(dict, &key, &hash);
502 ok(hr == S_OK, "got 0x%08x\n", hr);
503 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
504 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
505 expected);
507 expected = get_num_hash((FLOAT)(BYTE)int_hash_tests[i]);
508 V_VT(&key) = VT_UI1;
509 V_UI1(&key) = int_hash_tests[i];
510 VariantInit(&hash);
511 hr = IDictionary_get_HashVal(dict, &key, &hash);
512 ok(hr == S_OK, "got 0x%08x\n", hr);
513 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
514 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
515 expected);
517 ui1 = int_hash_tests[i];
518 V_VT(&key) = VT_UI1|VT_BYREF;
519 V_UI1REF(&key) = &ui1;
520 VariantInit(&hash);
521 hr = IDictionary_get_HashVal(dict, &key, &hash);
522 ok(hr == S_OK, "got 0x%08x\n", hr);
523 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
524 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
525 expected);
528 /* nan */
529 fx4.f = 10.0;
530 fx4.i.exp_bias = 0xff;
532 V_VT(&key) = VT_R4;
533 V_R4(&key) = fx4.f;
534 VariantInit(&hash);
535 hr = IDictionary_get_HashVal(dict, &key, &hash);
536 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
537 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
538 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ ||
539 V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash));
541 /* inf */
542 fx4.f = 10.0;
543 fx4.i.m = 0;
544 fx4.i.exp_bias = 0xff;
546 V_VT(&key) = VT_R4;
547 V_R4(&key) = fx4.f;
548 V_I4(&hash) = 10;
549 hr = IDictionary_get_HashVal(dict, &key, &hash);
550 ok(hr == S_OK, "got 0x%08x\n", hr);
551 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
552 ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash));
554 /* nan */
555 fx8.d = 10.0;
556 fx8.i.exp_bias = 0x7ff;
558 V_VT(&key) = VT_R8;
559 V_R8(&key) = fx8.d;
560 VariantInit(&hash);
561 hr = IDictionary_get_HashVal(dict, &key, &hash);
562 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
563 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
564 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ ||
565 V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash));
567 V_VT(&key) = VT_DATE;
568 V_DATE(&key) = fx8.d;
569 VariantInit(&hash);
570 hr = IDictionary_get_HashVal(dict, &key, &hash);
571 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
572 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
573 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ ||
574 V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash));
576 /* inf */
577 fx8.d = 10.0;
578 fx8.i.m_lo = 0;
579 fx8.i.m_hi = 0;
580 fx8.i.exp_bias = 0x7ff;
582 V_VT(&key) = VT_R8;
583 V_R8(&key) = fx8.d;
584 V_I4(&hash) = 10;
585 hr = IDictionary_get_HashVal(dict, &key, &hash);
586 ok(hr == S_OK, "got 0x%08x\n", hr);
587 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
588 ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash));
590 V_VT(&key) = VT_DATE;
591 V_DATE(&key) = fx8.d;
592 V_I4(&hash) = 10;
593 hr = IDictionary_get_HashVal(dict, &key, &hash);
594 ok(hr == S_OK, "got 0x%08x\n", hr);
595 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
596 ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash));
598 for (i = 0; i < ARRAY_SIZE(float_hash_tests); i++) {
599 double dbl;
600 FLOAT flt;
601 DATE date;
603 expected = get_num_hash(float_hash_tests[i]);
605 V_VT(&key) = VT_R4;
606 V_R4(&key) = float_hash_tests[i];
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);
614 flt = float_hash_tests[i];
615 V_VT(&key) = VT_R4|VT_BYREF;
616 V_R4REF(&key) = &flt;
617 VariantInit(&hash);
618 hr = IDictionary_get_HashVal(dict, &key, &hash);
619 ok(hr == S_OK, "got 0x%08x\n", hr);
620 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
621 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
622 expected);
624 V_VT(&key) = VT_R8;
625 V_R8(&key) = float_hash_tests[i];
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);
633 dbl = float_hash_tests[i];
634 V_VT(&key) = VT_R8|VT_BYREF;
635 V_R8REF(&key) = &dbl;
636 VariantInit(&hash);
637 hr = IDictionary_get_HashVal(dict, &key, &hash);
638 ok(hr == S_OK, "got 0x%08x\n", hr);
639 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
640 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
641 expected);
643 V_VT(&key) = VT_DATE;
644 V_DATE(&key) = float_hash_tests[i];
645 VariantInit(&hash);
646 hr = IDictionary_get_HashVal(dict, &key, &hash);
647 ok(hr == S_OK, "got 0x%08x\n", hr);
648 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
649 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
650 expected);
652 V_VT(&key) = VT_DATE|VT_BYREF;
653 date = float_hash_tests[i];
654 V_DATEREF(&key) = &date;
655 VariantInit(&hash);
656 hr = IDictionary_get_HashVal(dict, &key, &hash);
657 ok(hr == S_OK, "got 0x%08x\n", hr);
658 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
659 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
660 expected);
663 /* interface pointers as keys */
664 V_VT(&key) = VT_UNKNOWN;
665 V_UNKNOWN(&key) = 0;
666 VariantInit(&hash);
667 V_I4(&hash) = 1;
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) == 0, "got hash 0x%08x, expected 0\n", V_I4(&hash));
673 /* QI doesn't work */
674 V_VT(&key) = VT_UNKNOWN;
675 V_UNKNOWN(&key) = &test_unk2;
676 VariantInit(&hash);
677 expected = get_ptr_hash(&test_unk2);
678 hr = IDictionary_get_HashVal(dict, &key, &hash);
679 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k */, "got 0x%08x\n", hr);
680 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
681 ok(V_I4(&hash) == ~0u, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
683 V_VT(&key) = VT_UNKNOWN;
684 V_UNKNOWN(&key) = &test_unk;
685 VariantInit(&hash);
686 expected = get_ptr_hash(&test_unk);
687 hr = IDictionary_get_HashVal(dict, &key, &hash);
688 ok(hr == S_OK, "got 0x%08x\n", hr);
689 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
690 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
692 /* interface without IDispatch support */
693 V_VT(&key) = VT_DISPATCH;
694 V_DISPATCH(&key) = (IDispatch*)&test_unk;
695 VariantInit(&hash);
696 expected = get_ptr_hash(&test_unk);
697 hr = IDictionary_get_HashVal(dict, &key, &hash);
698 ok(hr == S_OK, "got 0x%08x\n", hr);
699 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
700 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
702 V_VT(&key) = VT_DISPATCH;
703 V_DISPATCH(&key) = &test_disp;
704 VariantInit(&hash);
705 expected = get_ptr_hash(&test_disp);
706 hr = IDictionary_get_HashVal(dict, &key, &hash);
707 ok(hr == S_OK, "got 0x%08x\n", hr);
708 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
709 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
711 /* same with BYREF */
712 if (0) { /* crashes on native */
713 V_VT(&key) = VT_UNKNOWN|VT_BYREF;
714 V_UNKNOWNREF(&key) = 0;
715 hr = IDictionary_get_HashVal(dict, &key, &hash);
717 unk = NULL;
718 V_VT(&key) = VT_UNKNOWN|VT_BYREF;
719 V_UNKNOWNREF(&key) = &unk;
720 VariantInit(&hash);
721 V_I4(&hash) = 1;
722 hr = IDictionary_get_HashVal(dict, &key, &hash);
723 ok(hr == S_OK, "got 0x%08x\n", hr);
724 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
725 ok(V_I4(&hash) == 0, "got hash 0x%08x, expected 0\n", V_I4(&hash));
727 V_VT(&key) = VT_UNKNOWN|VT_BYREF;
728 unk = &test_unk;
729 V_UNKNOWNREF(&key) = &unk;
730 VariantInit(&hash);
731 expected = get_ptr_hash(&test_unk);
732 hr = IDictionary_get_HashVal(dict, &key, &hash);
733 ok(hr == S_OK, "got 0x%08x\n", hr);
734 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
735 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
737 /* interface without IDispatch support */
738 V_VT(&key) = VT_DISPATCH|VT_BYREF;
739 unk = &test_unk;
740 V_DISPATCHREF(&key) = (IDispatch**)&unk;
741 VariantInit(&hash);
742 expected = get_ptr_hash(&test_unk);
743 hr = IDictionary_get_HashVal(dict, &key, &hash);
744 ok(hr == S_OK, "got 0x%08x\n", hr);
745 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
746 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
748 V_VT(&key) = VT_DISPATCH|VT_BYREF;
749 disp = &test_disp;
750 V_DISPATCHREF(&key) = &disp;
751 VariantInit(&hash);
752 expected = get_ptr_hash(&test_disp);
753 hr = IDictionary_get_HashVal(dict, &key, &hash);
754 ok(hr == S_OK, "got 0x%08x\n", hr);
755 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
756 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
758 IDictionary_Release(dict);
761 static void test_Exists(void)
763 VARIANT_BOOL exists;
764 IDictionary *dict;
765 VARIANT key, item;
766 HRESULT hr;
768 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
769 &IID_IDictionary, (void**)&dict);
770 ok(hr == S_OK, "got 0x%08x\n", hr);
772 if (0) /* crashes on native */
773 hr = IDictionary_Exists(dict, NULL, NULL);
775 V_VT(&key) = VT_I2;
776 V_I2(&key) = 0;
777 hr = IDictionary_Exists(dict, &key, NULL);
778 ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr);
780 V_VT(&key) = VT_I2;
781 V_I2(&key) = 0;
782 exists = VARIANT_TRUE;
783 hr = IDictionary_Exists(dict, &key, &exists);
784 ok(hr == S_OK, "got 0x%08x\n", hr);
785 ok(exists == VARIANT_FALSE, "got %x\n", exists);
787 VariantInit(&item);
788 hr = IDictionary_Add(dict, &key, &item);
789 ok(hr == S_OK, "got 0x%08x\n", hr);
791 V_VT(&key) = VT_R4;
792 V_R4(&key) = 0.0;
793 hr = IDictionary_Add(dict, &key, &item);
794 ok(hr == CTL_E_KEY_ALREADY_EXISTS, "got 0x%08x\n", hr);
796 V_VT(&key) = VT_I2;
797 V_I2(&key) = 0;
798 hr = IDictionary_Exists(dict, &key, NULL);
799 ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr);
801 V_VT(&key) = VT_I2;
802 V_I2(&key) = 0;
803 exists = VARIANT_FALSE;
804 hr = IDictionary_Exists(dict, &key, &exists);
805 ok(hr == S_OK, "got 0x%08x\n", hr);
806 ok(exists == VARIANT_TRUE, "got %x\n", exists);
808 /* key of different type, but resolves to same hash value */
809 V_VT(&key) = VT_R4;
810 V_R4(&key) = 0.0;
811 exists = VARIANT_FALSE;
812 hr = IDictionary_Exists(dict, &key, &exists);
813 ok(hr == S_OK, "got 0x%08x\n", hr);
814 ok(exists == VARIANT_TRUE, "got %x\n", exists);
816 IDictionary_Release(dict);
819 static void test_Keys(void)
821 VARIANT key, keys, item;
822 IDictionary *dict;
823 LONG index;
824 HRESULT hr;
826 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
827 &IID_IDictionary, (void**)&dict);
828 ok(hr == S_OK, "got 0x%08x\n", hr);
830 hr = IDictionary_Keys(dict, NULL);
831 ok(hr == S_OK, "got 0x%08x\n", hr);
833 VariantInit(&keys);
834 hr = IDictionary_Keys(dict, &keys);
835 ok(hr == S_OK, "got 0x%08x\n", hr);
836 ok(V_VT(&keys) == (VT_ARRAY|VT_VARIANT), "got %d\n", V_VT(&keys));
837 VariantClear(&keys);
839 V_VT(&key) = VT_R4;
840 V_R4(&key) = 0.0;
841 VariantInit(&item);
842 hr = IDictionary_Add(dict, &key, &item);
843 ok(hr == S_OK, "got 0x%08x\n", hr);
845 VariantInit(&keys);
846 hr = IDictionary_Keys(dict, &keys);
847 ok(hr == S_OK, "got 0x%08x\n", hr);
848 ok(V_VT(&keys) == (VT_ARRAY|VT_VARIANT), "got %d\n", V_VT(&keys));
850 VariantInit(&key);
851 index = 0;
852 hr = SafeArrayGetElement(V_ARRAY(&keys), &index, &key);
853 ok(hr == S_OK, "got 0x%08x\n", hr);
854 ok(V_VT(&key) == VT_R4, "got %d\n", V_VT(&key));
856 index = SafeArrayGetDim(V_ARRAY(&keys));
857 ok(index == 1, "got %d\n", index);
859 hr = SafeArrayGetUBound(V_ARRAY(&keys), 1, &index);
860 ok(hr == S_OK, "got 0x%08x\n", hr);
861 ok(index == 0, "got %d\n", index);
863 VariantClear(&keys);
865 IDictionary_Release(dict);
868 static void test_Remove(void)
870 VARIANT key, item;
871 IDictionary *dict;
872 HRESULT hr;
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);
878 if (0)
879 hr = IDictionary_Remove(dict, NULL);
881 /* nothing added yet */
882 V_VT(&key) = VT_R4;
883 V_R4(&key) = 0.0;
884 hr = IDictionary_Remove(dict, &key);
885 ok(hr == CTL_E_ELEMENT_NOT_FOUND, "got 0x%08x\n", hr);
887 VariantInit(&item);
888 hr = IDictionary_Add(dict, &key, &item);
889 ok(hr == S_OK, "got 0x%08x\n", hr);
891 hr = IDictionary_Remove(dict, &key);
892 ok(hr == S_OK, "got 0x%08x\n", hr);
894 IDictionary_Release(dict);
897 static void test_Item(void)
899 VARIANT key, item;
900 IDictionary *dict;
901 HRESULT hr;
903 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
904 &IID_IDictionary, (void**)&dict);
905 ok(hr == S_OK, "got 0x%08x\n", hr);
907 V_VT(&key) = VT_I2;
908 V_I2(&key) = 10;
909 V_VT(&item) = VT_I2;
910 V_I2(&item) = 123;
911 hr = IDictionary_get_Item(dict, &key, &item);
912 ok(hr == S_OK, "got 0x%08x\n", hr);
913 ok(V_VT(&item) == VT_EMPTY, "got %d\n", V_VT(&item));
915 V_VT(&key) = VT_I2;
916 V_I2(&key) = 10;
917 V_VT(&item) = VT_I2;
918 hr = IDictionary_get_Item(dict, &key, &item);
919 ok(hr == S_OK, "got 0x%08x\n", hr);
920 ok(V_VT(&item) == VT_EMPTY, "got %d\n", V_VT(&item));
922 IDictionary_Release(dict);
925 static void test_Add(void)
927 VARIANT key, item;
928 IDictionary *dict;
929 HRESULT hr;
930 BSTR str;
932 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
933 &IID_IDictionary, (void**)&dict);
934 ok(hr == S_OK, "got 0x%08x\n", hr);
936 str = SysAllocString(L"testW");
937 V_VT(&key) = VT_I2;
938 V_I2(&key) = 1;
939 V_VT(&item) = VT_BSTR|VT_BYREF;
940 V_BSTRREF(&item) = &str;
941 hr = IDictionary_Add(dict, &key, &item);
942 ok(hr == S_OK, "got 0x%08x\n", hr);
944 hr = IDictionary_get_Item(dict, &key, &item);
945 ok(hr == S_OK, "got 0x%08x\n", hr);
946 ok(V_VT(&item) == VT_BSTR, "got %d\n", V_VT(&item));
948 SysFreeString(str);
950 IDictionary_Release(dict);
953 static void test_IEnumVARIANT(void)
955 IUnknown *enum1, *enum2;
956 IEnumVARIANT *enumvar;
957 VARIANT key, item;
958 IDictionary *dict;
959 ULONG fetched;
960 HRESULT hr;
962 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
963 &IID_IDictionary, (void**)&dict);
964 ok(hr == S_OK, "got 0x%08x\n", hr);
966 if (0) /* crashes on native */
967 hr = IDictionary__NewEnum(dict, NULL);
969 hr = IDictionary__NewEnum(dict, &enum1);
970 ok(hr == S_OK, "got 0x%08x\n", hr);
972 hr = IDictionary__NewEnum(dict, &enum2);
973 ok(hr == S_OK, "got 0x%08x\n", hr);
974 ok(enum1 != enum2, "got %p, %p\n", enum2, enum1);
975 IUnknown_Release(enum2);
977 hr = IUnknown_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enumvar);
978 ok(hr == S_OK, "got 0x%08x\n", hr);
979 IUnknown_Release(enum1);
981 /* dictionary is empty */
982 hr = IEnumVARIANT_Skip(enumvar, 1);
983 ok(hr == S_FALSE, "got 0x%08x\n", hr);
985 hr = IEnumVARIANT_Skip(enumvar, 0);
986 ok(hr == S_OK, "got 0x%08x\n", hr);
988 V_VT(&key) = VT_I2;
989 V_I2(&key) = 1;
990 V_VT(&item) = VT_I4;
991 V_I4(&item) = 100;
992 hr = IDictionary_Add(dict, &key, &item);
993 ok(hr == S_OK, "got 0x%08x\n", hr);
995 hr = IEnumVARIANT_Skip(enumvar, 0);
996 ok(hr == S_OK, "got 0x%08x\n", hr);
998 hr = IEnumVARIANT_Reset(enumvar);
999 ok(hr == S_OK, "got 0x%08x\n", hr);
1000 hr = IEnumVARIANT_Skip(enumvar, 1);
1001 ok(hr == S_OK, "got 0x%08x\n", hr);
1002 hr = IEnumVARIANT_Skip(enumvar, 1);
1003 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1005 V_VT(&key) = VT_I2;
1006 V_I2(&key) = 4000;
1007 V_VT(&item) = VT_I4;
1008 V_I4(&item) = 200;
1009 hr = IDictionary_Add(dict, &key, &item);
1010 ok(hr == S_OK, "got 0x%08x\n", hr);
1012 V_VT(&key) = VT_I2;
1013 V_I2(&key) = 0;
1014 V_VT(&item) = VT_I4;
1015 V_I4(&item) = 300;
1016 hr = IDictionary_Add(dict, &key, &item);
1017 ok(hr == S_OK, "got 0x%08x\n", hr);
1019 hr = IEnumVARIANT_Reset(enumvar);
1020 ok(hr == S_OK, "got 0x%08x\n", hr);
1022 VariantInit(&key);
1023 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1024 ok(hr == S_OK, "got 0x%08x\n", hr);
1025 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
1026 ok(V_I2(&key) == 1, "got %d\n", V_I2(&key));
1027 ok(fetched == 1, "got %u\n", fetched);
1029 hr = IEnumVARIANT_Reset(enumvar);
1030 ok(hr == S_OK, "got 0x%08x\n", hr);
1032 hr = IDictionary_Remove(dict, &key);
1033 ok(hr == S_OK, "got 0x%08x\n", hr);
1035 VariantInit(&key);
1036 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1037 ok(hr == S_OK, "got 0x%08x\n", hr);
1038 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
1039 ok(V_I2(&key) == 4000, "got %d\n", V_I2(&key));
1040 ok(fetched == 1, "got %u\n", fetched);
1042 VariantInit(&key);
1043 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1044 ok(hr == S_OK, "got 0x%08x\n", hr);
1045 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
1046 ok(V_I2(&key) == 0, "got %d\n", V_I2(&key));
1047 ok(fetched == 1, "got %u\n", fetched);
1049 /* enumeration reached the bottom, add one more pair */
1050 VariantInit(&key);
1051 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1052 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1054 V_VT(&key) = VT_I2;
1055 V_I2(&key) = 13;
1056 V_VT(&item) = VT_I4;
1057 V_I4(&item) = 350;
1058 hr = IDictionary_Add(dict, &key, &item);
1059 ok(hr == S_OK, "got 0x%08x\n", hr);
1061 /* still doesn't work until Reset() */
1062 VariantInit(&key);
1063 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1064 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1066 IEnumVARIANT_Release(enumvar);
1067 IDictionary_Release(dict);
1070 START_TEST(dictionary)
1072 IDispatch *disp;
1073 HRESULT hr;
1075 CoInitialize(NULL);
1077 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1078 &IID_IDispatch, (void**)&disp);
1079 if(FAILED(hr)) {
1080 win_skip("Dictionary object is not supported: %08x\n", hr);
1081 CoUninitialize();
1082 return;
1084 IDispatch_Release(disp);
1086 test_interfaces();
1087 test_comparemode();
1088 test_hash_value();
1089 test_Exists();
1090 test_Keys();
1091 test_Remove();
1092 test_Item();
1093 test_Add();
1094 test_IEnumVARIANT();
1096 CoUninitialize();