qmgr: Update to IBackgroundCopyFile2.
[wine.git] / dlls / scrrun / tests / dictionary.c
blobe1c80f91f649ccffcad42f09acf66d28608c843f
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 static void test_interfaces(void)
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;
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);
51 VariantInit(&key);
52 VariantInit(&value);
54 hr = IDispatch_QueryInterface(disp, &IID_IDictionary, (void**)&dict);
55 ok(hr == S_OK, "got 0x%08x, expected 0x%08x\n", hr, S_OK);
57 hr = IDispatch_QueryInterface(disp, &IID_IObjectWithSite, (void**)&site);
58 ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE);
60 hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
61 ok(hr == E_NOINTERFACE, "got 0x%08x, expected 0x%08x\n", hr, E_NOINTERFACE);
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);
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);
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);
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);
89 IDictionary_Release(dict);
90 IDispatch_Release(disp);
93 static void test_comparemode(void)
95 CompareMethod method;
96 IDictionary *dict;
97 VARIANT key, item;
98 HRESULT hr;
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);
104 if (0) /* crashes on native */
105 hr = IDictionary_get_CompareMode(dict, NULL);
107 method = 10;
108 hr = IDictionary_get_CompareMode(dict, &method);
109 ok(hr == S_OK, "got 0x%08x\n", hr);
110 ok(method == BinaryCompare, "got %d\n", method);
112 /* invalid mode value is not checked */
113 hr = IDictionary_put_CompareMode(dict, 10);
114 ok(hr == S_OK, "got 0x%08x\n", hr);
116 hr = IDictionary_get_CompareMode(dict, &method);
117 ok(hr == S_OK, "got 0x%08x\n", hr);
118 ok(method == 10, "got %d\n", method);
120 hr = IDictionary_put_CompareMode(dict, DatabaseCompare);
121 ok(hr == S_OK, "got 0x%08x\n", hr);
123 hr = IDictionary_get_CompareMode(dict, &method);
124 ok(hr == S_OK, "got 0x%08x\n", hr);
125 ok(method == DatabaseCompare, "got %d\n", method);
127 /* try to change mode of a non-empty dict */
128 V_VT(&key) = VT_I2;
129 V_I2(&key) = 0;
130 VariantInit(&item);
131 hr = IDictionary_Add(dict, &key, &item);
132 ok(hr == S_OK, "got 0x%08x\n", hr);
134 hr = IDictionary_put_CompareMode(dict, BinaryCompare);
135 ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr);
137 IDictionary_Release(dict);
140 static DWORD get_str_hash(const WCHAR *str, CompareMethod method)
142 DWORD hash = 0;
144 while (*str) {
145 WCHAR ch;
147 if (method == TextCompare || method == DatabaseCompare)
148 ch = PtrToInt(CharLowerW(IntToPtr(*str)));
149 else
150 ch = *str;
152 hash += (hash << 4) + ch;
153 str++;
156 return hash % 1201;
159 static DWORD get_num_hash(FLOAT num)
161 return (*((DWORD*)&num)) % 1201;
164 static DWORD get_ptr_hash(void *ptr)
166 return PtrToUlong(ptr) % 1201;
169 typedef union
171 struct
173 unsigned int m : 23;
174 unsigned int exp_bias : 8;
175 unsigned int sign : 1;
176 } i;
177 float f;
178 } R4_FIELDS;
180 typedef union
182 struct
184 unsigned int m_lo : 32; /* 52 bits of precision */
185 unsigned int m_hi : 20;
186 unsigned int exp_bias : 11; /* bias == 1023 */
187 unsigned int sign : 1;
188 } i;
189 double d;
190 } R8_FIELDS;
192 static HRESULT WINAPI test_unk_QI(IUnknown *iface, REFIID riid, void **obj)
194 if (IsEqualIID(riid, &IID_IUnknown)) {
195 *obj = iface;
196 return S_OK;
199 ok(0, "unexpected %s\n", wine_dbgstr_guid(riid));
200 *obj = NULL;
201 return E_NOINTERFACE;
204 static HRESULT WINAPI test_unk_no_QI(IUnknown *iface, REFIID riid, void **obj)
206 *obj = NULL;
207 return E_NOINTERFACE;
210 static ULONG WINAPI test_unk_AddRef(IUnknown *iface)
212 ok(0, "unxpected\n");
213 return 2;
216 static ULONG WINAPI test_unk_Release(IUnknown *iface)
218 return 1;
221 static const IUnknownVtbl test_unk_vtbl = {
222 test_unk_QI,
223 test_unk_AddRef,
224 test_unk_Release
227 static const IUnknownVtbl test_unk_no_vtbl = {
228 test_unk_no_QI,
229 test_unk_AddRef,
230 test_unk_Release
233 static HRESULT WINAPI test_disp_QI(IDispatch *iface, REFIID riid, void **obj)
235 if (IsEqualIID(riid, &IID_IDispatch) || IsEqualIID(riid, &IID_IUnknown)) {
236 *obj = iface;
237 return S_OK;
240 ok(0, "unexpected %s\n", wine_dbgstr_guid(riid));
241 *obj = NULL;
242 return E_NOINTERFACE;
245 static ULONG WINAPI test_disp_AddRef(IDispatch *iface)
247 ok(0, "unxpected\n");
248 return 2;
251 static ULONG WINAPI test_disp_Release(IDispatch *iface)
253 return 1;
256 static HRESULT WINAPI test_disp_GetTypeInfoCount(IDispatch *iface, UINT *count)
258 ok(0, "unexpected call\n");
259 return E_NOTIMPL;
262 static HRESULT WINAPI test_disp_GetTypeInfo(IDispatch *iface, UINT index, LCID lcid, ITypeInfo **ti)
264 ok(0, "unexpected call\n");
265 return E_NOTIMPL;
268 static HRESULT WINAPI test_disp_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names,
269 UINT name_count, LCID lcid, DISPID *dispid)
271 ok(0, "unexpected call\n");
272 return E_NOTIMPL;
275 static HRESULT WINAPI test_disp_Invoke(IDispatch *iface, DISPID dispid, REFIID riid,
276 LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *arg_err)
278 ok(0, "unexpected call\n");
279 return E_NOTIMPL;
282 static const IDispatchVtbl test_disp_vtbl = {
283 test_disp_QI,
284 test_disp_AddRef,
285 test_disp_Release,
286 test_disp_GetTypeInfoCount,
287 test_disp_GetTypeInfo,
288 test_disp_GetIDsOfNames,
289 test_disp_Invoke
292 static IUnknown test_unk = { &test_unk_vtbl };
293 static IUnknown test_unk2 = { &test_unk_no_vtbl };
294 static IDispatch test_disp = { &test_disp_vtbl };
296 static void test_hash_value(void)
298 /* string test data */
299 static const WCHAR str_hash_tests[][10] = {
300 {'a','b','c','d',0},
301 {'a','B','C','d','1',0},
302 {'1','2','3',0},
303 {'A',0},
304 {'a',0},
305 { 0 }
308 static const int int_hash_tests[] = {
309 0, -1, 100, 1, 255
312 static const FLOAT float_hash_tests[] = {
313 0.0, -1.0, 100.0, 1.0, 255.0, 1.234
316 IDictionary *dict;
317 VARIANT key, hash;
318 IDispatch *disp;
319 DWORD expected;
320 IUnknown *unk;
321 R8_FIELDS fx8;
322 R4_FIELDS fx4;
323 HRESULT hr;
324 unsigned i;
326 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
327 &IID_IDictionary, (void**)&dict);
328 ok(hr == S_OK, "got 0x%08x\n", hr);
330 V_VT(&key) = VT_BSTR;
331 V_BSTR(&key) = NULL;
332 VariantInit(&hash);
333 hr = IDictionary_get_HashVal(dict, &key, &hash);
334 ok(hr == S_OK, "got 0x%08x\n", hr);
335 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
336 ok(V_I4(&hash) == 0, "got %d\n", V_I4(&hash));
338 for (i = 0; i < sizeof(str_hash_tests)/sizeof(str_hash_tests[0]); i++) {
339 expected = get_str_hash(str_hash_tests[i], BinaryCompare);
341 hr = IDictionary_put_CompareMode(dict, BinaryCompare);
342 ok(hr == S_OK, "got 0x%08x\n", hr);
344 V_VT(&key) = VT_BSTR;
345 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
346 VariantInit(&hash);
347 hr = IDictionary_get_HashVal(dict, &key, &hash);
348 ok(hr == S_OK, "got 0x%08x\n", hr);
349 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
350 ok(V_I4(&hash) == expected, "%d: binary mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
351 expected);
352 VariantClear(&key);
354 expected = get_str_hash(str_hash_tests[i], TextCompare);
355 hr = IDictionary_put_CompareMode(dict, TextCompare);
356 ok(hr == S_OK, "got 0x%08x\n", hr);
358 V_VT(&key) = VT_BSTR;
359 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
360 VariantInit(&hash);
361 hr = IDictionary_get_HashVal(dict, &key, &hash);
362 ok(hr == S_OK, "got 0x%08x\n", hr);
363 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
364 ok(V_I4(&hash) == expected, "%d: text mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
365 expected);
366 VariantClear(&key);
368 expected = get_str_hash(str_hash_tests[i], DatabaseCompare);
369 hr = IDictionary_put_CompareMode(dict, DatabaseCompare);
370 ok(hr == S_OK, "got 0x%08x\n", hr);
372 V_VT(&key) = VT_BSTR;
373 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
374 VariantInit(&hash);
375 hr = IDictionary_get_HashVal(dict, &key, &hash);
376 ok(hr == S_OK, "got 0x%08x\n", hr);
377 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
378 ok(V_I4(&hash) == expected, "%d: db mode: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
379 expected);
380 VariantClear(&key);
383 V_VT(&key) = VT_INT;
384 V_INT(&key) = 1;
385 VariantInit(&hash);
386 hr = IDictionary_get_HashVal(dict, &key, &hash);
387 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
388 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
389 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
391 V_VT(&key) = VT_UINT;
392 V_UINT(&key) = 1;
393 VariantInit(&hash);
394 hr = IDictionary_get_HashVal(dict, &key, &hash);
395 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
396 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
397 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
399 V_VT(&key) = VT_I1;
400 V_I1(&key) = 1;
401 VariantInit(&hash);
402 hr = IDictionary_get_HashVal(dict, &key, &hash);
403 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
404 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
405 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0xa1), "got hash 0x%08x\n", V_I4(&hash));
407 V_VT(&key) = VT_I8;
408 V_I8(&key) = 1;
409 VariantInit(&hash);
410 hr = IDictionary_get_HashVal(dict, &key, &hash);
411 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
412 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
413 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
415 V_VT(&key) = VT_UI2;
416 V_UI2(&key) = 1;
417 VariantInit(&hash);
418 hr = IDictionary_get_HashVal(dict, &key, &hash);
419 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
420 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
421 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
423 V_VT(&key) = VT_UI4;
424 V_UI4(&key) = 1;
425 VariantInit(&hash);
426 hr = IDictionary_get_HashVal(dict, &key, &hash);
427 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
428 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
429 ok(V_I4(&hash) == ~0u, "got hash 0x%08x\n", V_I4(&hash));
431 for (i = 0; i < sizeof(int_hash_tests)/sizeof(int_hash_tests[0]); i++) {
432 SHORT i2;
433 BYTE ui1;
434 LONG i4;
436 expected = get_num_hash(int_hash_tests[i]);
438 V_VT(&key) = VT_I2;
439 V_I2(&key) = int_hash_tests[i];
440 VariantInit(&hash);
441 hr = IDictionary_get_HashVal(dict, &key, &hash);
442 ok(hr == S_OK, "got 0x%08x\n", hr);
443 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
444 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
445 expected);
447 i2 = int_hash_tests[i];
448 V_VT(&key) = VT_I2|VT_BYREF;
449 V_I2REF(&key) = &i2;
450 VariantInit(&hash);
451 hr = IDictionary_get_HashVal(dict, &key, &hash);
452 ok(hr == S_OK, "got 0x%08x\n", hr);
453 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
454 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
455 expected);
457 V_VT(&key) = VT_I4;
458 V_I4(&key) = int_hash_tests[i];
459 VariantInit(&hash);
460 hr = IDictionary_get_HashVal(dict, &key, &hash);
461 ok(hr == S_OK, "got 0x%08x\n", hr);
462 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
463 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
464 expected);
466 i4 = int_hash_tests[i];
467 V_VT(&key) = VT_I4|VT_BYREF;
468 V_I4REF(&key) = &i4;
469 VariantInit(&hash);
470 hr = IDictionary_get_HashVal(dict, &key, &hash);
471 ok(hr == S_OK, "got 0x%08x\n", hr);
472 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
473 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
474 expected);
476 expected = get_num_hash((FLOAT)(BYTE)int_hash_tests[i]);
477 V_VT(&key) = VT_UI1;
478 V_UI1(&key) = int_hash_tests[i];
479 VariantInit(&hash);
480 hr = IDictionary_get_HashVal(dict, &key, &hash);
481 ok(hr == S_OK, "got 0x%08x\n", hr);
482 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
483 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
484 expected);
486 ui1 = int_hash_tests[i];
487 V_VT(&key) = VT_UI1|VT_BYREF;
488 V_UI1REF(&key) = &ui1;
489 VariantInit(&hash);
490 hr = IDictionary_get_HashVal(dict, &key, &hash);
491 ok(hr == S_OK, "got 0x%08x\n", hr);
492 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
493 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
494 expected);
497 /* nan */
498 fx4.f = 10.0;
499 fx4.i.exp_bias = 0xff;
501 V_VT(&key) = VT_R4;
502 V_R4(&key) = fx4.f;
503 VariantInit(&hash);
504 hr = IDictionary_get_HashVal(dict, &key, &hash);
505 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
506 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
507 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ ||
508 V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash));
510 /* inf */
511 fx4.f = 10.0;
512 fx4.i.m = 0;
513 fx4.i.exp_bias = 0xff;
515 V_VT(&key) = VT_R4;
516 V_R4(&key) = fx4.f;
517 V_I4(&hash) = 10;
518 hr = IDictionary_get_HashVal(dict, &key, &hash);
519 ok(hr == S_OK, "got 0x%08x\n", hr);
520 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
521 ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash));
523 /* nan */
524 fx8.d = 10.0;
525 fx8.i.exp_bias = 0x7ff;
527 V_VT(&key) = VT_R8;
528 V_R8(&key) = fx8.d;
529 VariantInit(&hash);
530 hr = IDictionary_get_HashVal(dict, &key, &hash);
531 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
532 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
533 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ ||
534 V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash));
536 V_VT(&key) = VT_DATE;
537 V_DATE(&key) = fx8.d;
538 VariantInit(&hash);
539 hr = IDictionary_get_HashVal(dict, &key, &hash);
540 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "got 0x%08x\n", hr);
541 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
542 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ ||
543 V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "got hash 0x%08x\n", V_I4(&hash));
545 /* inf */
546 fx8.d = 10.0;
547 fx8.i.m_lo = 0;
548 fx8.i.m_hi = 0;
549 fx8.i.exp_bias = 0x7ff;
551 V_VT(&key) = VT_R8;
552 V_R8(&key) = fx8.d;
553 V_I4(&hash) = 10;
554 hr = IDictionary_get_HashVal(dict, &key, &hash);
555 ok(hr == S_OK, "got 0x%08x\n", hr);
556 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
557 ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash));
559 V_VT(&key) = VT_DATE;
560 V_DATE(&key) = fx8.d;
561 V_I4(&hash) = 10;
562 hr = IDictionary_get_HashVal(dict, &key, &hash);
563 ok(hr == S_OK, "got 0x%08x\n", hr);
564 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
565 ok(V_I4(&hash) == 0, "got hash 0x%08x\n", V_I4(&hash));
567 for (i = 0; i < sizeof(float_hash_tests)/sizeof(float_hash_tests[0]); i++) {
568 double dbl;
569 FLOAT flt;
570 DATE date;
572 expected = get_num_hash(float_hash_tests[i]);
574 V_VT(&key) = VT_R4;
575 V_R4(&key) = float_hash_tests[i];
576 VariantInit(&hash);
577 hr = IDictionary_get_HashVal(dict, &key, &hash);
578 ok(hr == S_OK, "got 0x%08x\n", hr);
579 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
580 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
581 expected);
583 flt = float_hash_tests[i];
584 V_VT(&key) = VT_R4|VT_BYREF;
585 V_R4REF(&key) = &flt;
586 VariantInit(&hash);
587 hr = IDictionary_get_HashVal(dict, &key, &hash);
588 ok(hr == S_OK, "got 0x%08x\n", hr);
589 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
590 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
591 expected);
593 V_VT(&key) = VT_R8;
594 V_R8(&key) = float_hash_tests[i];
595 VariantInit(&hash);
596 hr = IDictionary_get_HashVal(dict, &key, &hash);
597 ok(hr == S_OK, "got 0x%08x\n", hr);
598 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
599 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
600 expected);
602 dbl = float_hash_tests[i];
603 V_VT(&key) = VT_R8|VT_BYREF;
604 V_R8REF(&key) = &dbl;
605 VariantInit(&hash);
606 hr = IDictionary_get_HashVal(dict, &key, &hash);
607 ok(hr == S_OK, "got 0x%08x\n", hr);
608 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
609 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
610 expected);
612 V_VT(&key) = VT_DATE;
613 V_DATE(&key) = float_hash_tests[i];
614 VariantInit(&hash);
615 hr = IDictionary_get_HashVal(dict, &key, &hash);
616 ok(hr == S_OK, "got 0x%08x\n", hr);
617 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
618 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
619 expected);
621 V_VT(&key) = VT_DATE|VT_BYREF;
622 date = float_hash_tests[i];
623 V_DATEREF(&key) = &date;
624 VariantInit(&hash);
625 hr = IDictionary_get_HashVal(dict, &key, &hash);
626 ok(hr == S_OK, "got 0x%08x\n", hr);
627 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
628 ok(V_I4(&hash) == expected, "%d: got hash 0x%08x, expected 0x%08x\n", i, V_I4(&hash),
629 expected);
632 /* interface pointers as keys */
633 V_VT(&key) = VT_UNKNOWN;
634 V_UNKNOWN(&key) = 0;
635 VariantInit(&hash);
636 V_I4(&hash) = 1;
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) == 0, "got hash 0x%08x, expected 0\n", V_I4(&hash));
642 /* QI doesn't work */
643 V_VT(&key) = VT_UNKNOWN;
644 V_UNKNOWN(&key) = &test_unk2;
645 VariantInit(&hash);
646 expected = get_ptr_hash(&test_unk2);
647 hr = IDictionary_get_HashVal(dict, &key, &hash);
648 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k */, "got 0x%08x\n", hr);
649 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
650 ok(V_I4(&hash) == ~0u, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
652 V_VT(&key) = VT_UNKNOWN;
653 V_UNKNOWN(&key) = &test_unk;
654 VariantInit(&hash);
655 expected = get_ptr_hash(&test_unk);
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, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
661 /* interface without IDispatch support */
662 V_VT(&key) = VT_DISPATCH;
663 V_DISPATCH(&key) = (IDispatch*)&test_unk;
664 VariantInit(&hash);
665 expected = get_ptr_hash(&test_unk);
666 hr = IDictionary_get_HashVal(dict, &key, &hash);
667 ok(hr == S_OK, "got 0x%08x\n", hr);
668 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
669 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
671 V_VT(&key) = VT_DISPATCH;
672 V_DISPATCH(&key) = &test_disp;
673 VariantInit(&hash);
674 expected = get_ptr_hash(&test_disp);
675 hr = IDictionary_get_HashVal(dict, &key, &hash);
676 ok(hr == S_OK, "got 0x%08x\n", hr);
677 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
678 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
680 /* same with BYREF */
681 if (0) { /* crashes on native */
682 V_VT(&key) = VT_UNKNOWN|VT_BYREF;
683 V_UNKNOWNREF(&key) = 0;
684 hr = IDictionary_get_HashVal(dict, &key, &hash);
686 unk = NULL;
687 V_VT(&key) = VT_UNKNOWN|VT_BYREF;
688 V_UNKNOWNREF(&key) = &unk;
689 VariantInit(&hash);
690 V_I4(&hash) = 1;
691 hr = IDictionary_get_HashVal(dict, &key, &hash);
692 ok(hr == S_OK, "got 0x%08x\n", hr);
693 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
694 ok(V_I4(&hash) == 0, "got hash 0x%08x, expected 0\n", V_I4(&hash));
696 V_VT(&key) = VT_UNKNOWN|VT_BYREF;
697 unk = &test_unk;
698 V_UNKNOWNREF(&key) = &unk;
699 VariantInit(&hash);
700 expected = get_ptr_hash(&test_unk);
701 hr = IDictionary_get_HashVal(dict, &key, &hash);
702 ok(hr == S_OK, "got 0x%08x\n", hr);
703 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
704 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
706 /* interface without IDispatch support */
707 V_VT(&key) = VT_DISPATCH|VT_BYREF;
708 unk = &test_unk;
709 V_DISPATCHREF(&key) = (IDispatch**)&unk;
710 VariantInit(&hash);
711 expected = get_ptr_hash(&test_unk);
712 hr = IDictionary_get_HashVal(dict, &key, &hash);
713 ok(hr == S_OK, "got 0x%08x\n", hr);
714 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
715 ok(V_I4(&hash) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
717 V_VT(&key) = VT_DISPATCH|VT_BYREF;
718 disp = &test_disp;
719 V_DISPATCHREF(&key) = &disp;
720 VariantInit(&hash);
721 expected = get_ptr_hash(&test_disp);
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) == expected, "got hash 0x%08x, expected 0x%08x\n", V_I4(&hash), expected);
727 IDictionary_Release(dict);
730 static void test_Exists(void)
732 VARIANT_BOOL exists;
733 IDictionary *dict;
734 VARIANT key, item;
735 HRESULT hr;
737 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
738 &IID_IDictionary, (void**)&dict);
739 ok(hr == S_OK, "got 0x%08x\n", hr);
741 if (0) /* crashes on native */
742 hr = IDictionary_Exists(dict, NULL, NULL);
744 V_VT(&key) = VT_I2;
745 V_I2(&key) = 0;
746 hr = IDictionary_Exists(dict, &key, NULL);
747 ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr);
749 V_VT(&key) = VT_I2;
750 V_I2(&key) = 0;
751 exists = VARIANT_TRUE;
752 hr = IDictionary_Exists(dict, &key, &exists);
753 ok(hr == S_OK, "got 0x%08x\n", hr);
754 ok(exists == VARIANT_FALSE, "got %x\n", exists);
756 VariantInit(&item);
757 hr = IDictionary_Add(dict, &key, &item);
758 ok(hr == S_OK, "got 0x%08x\n", hr);
760 V_VT(&key) = VT_R4;
761 V_R4(&key) = 0.0;
762 hr = IDictionary_Add(dict, &key, &item);
763 ok(hr == CTL_E_KEY_ALREADY_EXISTS, "got 0x%08x\n", hr);
765 V_VT(&key) = VT_I2;
766 V_I2(&key) = 0;
767 hr = IDictionary_Exists(dict, &key, NULL);
768 ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "got 0x%08x\n", hr);
770 V_VT(&key) = VT_I2;
771 V_I2(&key) = 0;
772 exists = VARIANT_FALSE;
773 hr = IDictionary_Exists(dict, &key, &exists);
774 ok(hr == S_OK, "got 0x%08x\n", hr);
775 ok(exists == VARIANT_TRUE, "got %x\n", exists);
777 /* key of different type, but resolves to same hash value */
778 V_VT(&key) = VT_R4;
779 V_R4(&key) = 0.0;
780 exists = VARIANT_FALSE;
781 hr = IDictionary_Exists(dict, &key, &exists);
782 ok(hr == S_OK, "got 0x%08x\n", hr);
783 ok(exists == VARIANT_TRUE, "got %x\n", exists);
785 IDictionary_Release(dict);
788 static void test_Keys(void)
790 VARIANT key, keys, item;
791 IDictionary *dict;
792 LONG index;
793 HRESULT hr;
795 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
796 &IID_IDictionary, (void**)&dict);
797 ok(hr == S_OK, "got 0x%08x\n", hr);
799 hr = IDictionary_Keys(dict, NULL);
800 ok(hr == S_OK, "got 0x%08x\n", hr);
802 VariantInit(&keys);
803 hr = IDictionary_Keys(dict, &keys);
804 ok(hr == S_OK, "got 0x%08x\n", hr);
805 ok(V_VT(&keys) == (VT_ARRAY|VT_VARIANT), "got %d\n", V_VT(&keys));
806 VariantClear(&keys);
808 V_VT(&key) = VT_R4;
809 V_R4(&key) = 0.0;
810 VariantInit(&item);
811 hr = IDictionary_Add(dict, &key, &item);
812 ok(hr == S_OK, "got 0x%08x\n", hr);
814 VariantInit(&keys);
815 hr = IDictionary_Keys(dict, &keys);
816 ok(hr == S_OK, "got 0x%08x\n", hr);
817 ok(V_VT(&keys) == (VT_ARRAY|VT_VARIANT), "got %d\n", V_VT(&keys));
819 VariantInit(&key);
820 index = 0;
821 hr = SafeArrayGetElement(V_ARRAY(&keys), &index, &key);
822 ok(hr == S_OK, "got 0x%08x\n", hr);
823 ok(V_VT(&key) == VT_R4, "got %d\n", V_VT(&key));
825 index = SafeArrayGetDim(V_ARRAY(&keys));
826 ok(index == 1, "got %d\n", index);
828 hr = SafeArrayGetUBound(V_ARRAY(&keys), 1, &index);
829 ok(hr == S_OK, "got 0x%08x\n", hr);
830 ok(index == 0, "got %d\n", index);
832 VariantClear(&keys);
834 IDictionary_Release(dict);
837 static void test_Remove(void)
839 VARIANT key, item;
840 IDictionary *dict;
841 HRESULT hr;
843 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
844 &IID_IDictionary, (void**)&dict);
845 ok(hr == S_OK, "got 0x%08x\n", hr);
847 if (0)
848 hr = IDictionary_Remove(dict, NULL);
850 /* nothing added yet */
851 V_VT(&key) = VT_R4;
852 V_R4(&key) = 0.0;
853 hr = IDictionary_Remove(dict, &key);
854 ok(hr == CTL_E_ELEMENT_NOT_FOUND, "got 0x%08x\n", hr);
856 VariantInit(&item);
857 hr = IDictionary_Add(dict, &key, &item);
858 ok(hr == S_OK, "got 0x%08x\n", hr);
860 hr = IDictionary_Remove(dict, &key);
861 ok(hr == S_OK, "got 0x%08x\n", hr);
863 IDictionary_Release(dict);
866 static void test_Item(void)
868 VARIANT key, item;
869 IDictionary *dict;
870 HRESULT hr;
872 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
873 &IID_IDictionary, (void**)&dict);
874 ok(hr == S_OK, "got 0x%08x\n", hr);
876 V_VT(&key) = VT_I2;
877 V_I2(&key) = 10;
878 V_VT(&item) = VT_I2;
879 V_I2(&item) = 123;
880 hr = IDictionary_get_Item(dict, &key, &item);
881 ok(hr == S_OK, "got 0x%08x\n", hr);
882 ok(V_VT(&item) == VT_EMPTY, "got %d\n", V_VT(&item));
884 V_VT(&key) = VT_I2;
885 V_I2(&key) = 10;
886 V_VT(&item) = VT_I2;
887 hr = IDictionary_get_Item(dict, &key, &item);
888 ok(hr == S_OK, "got 0x%08x\n", hr);
889 ok(V_VT(&item) == VT_EMPTY, "got %d\n", V_VT(&item));
891 IDictionary_Release(dict);
894 static void test_Add(void)
896 static const WCHAR testW[] = {'t','e','s','t','W',0};
897 VARIANT key, item;
898 IDictionary *dict;
899 HRESULT hr;
900 BSTR str;
902 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
903 &IID_IDictionary, (void**)&dict);
904 ok(hr == S_OK, "got 0x%08x\n", hr);
906 str = SysAllocString(testW);
907 V_VT(&key) = VT_I2;
908 V_I2(&key) = 1;
909 V_VT(&item) = VT_BSTR|VT_BYREF;
910 V_BSTRREF(&item) = &str;
911 hr = IDictionary_Add(dict, &key, &item);
912 ok(hr == S_OK, "got 0x%08x\n", hr);
914 hr = IDictionary_get_Item(dict, &key, &item);
915 ok(hr == S_OK, "got 0x%08x\n", hr);
916 ok(V_VT(&item) == VT_BSTR, "got %d\n", V_VT(&item));
918 SysFreeString(str);
920 IDictionary_Release(dict);
923 static void test_IEnumVARIANT(void)
925 IUnknown *enum1, *enum2;
926 IEnumVARIANT *enumvar;
927 VARIANT key, item;
928 IDictionary *dict;
929 ULONG fetched;
930 HRESULT hr;
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 if (0) /* crashes on native */
937 hr = IDictionary__NewEnum(dict, NULL);
939 hr = IDictionary__NewEnum(dict, &enum1);
940 ok(hr == S_OK, "got 0x%08x\n", hr);
942 hr = IDictionary__NewEnum(dict, &enum2);
943 ok(hr == S_OK, "got 0x%08x\n", hr);
944 ok(enum1 != enum2, "got %p, %p\n", enum2, enum1);
945 IUnknown_Release(enum2);
947 hr = IUnknown_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enumvar);
948 ok(hr == S_OK, "got 0x%08x\n", hr);
949 IUnknown_Release(enum1);
951 /* dictionary is empty */
952 hr = IEnumVARIANT_Skip(enumvar, 1);
953 ok(hr == S_FALSE, "got 0x%08x\n", hr);
955 hr = IEnumVARIANT_Skip(enumvar, 0);
956 ok(hr == S_OK, "got 0x%08x\n", hr);
958 V_VT(&key) = VT_I2;
959 V_I2(&key) = 1;
960 V_VT(&item) = VT_I4;
961 V_I4(&item) = 100;
962 hr = IDictionary_Add(dict, &key, &item);
963 ok(hr == S_OK, "got 0x%08x\n", hr);
965 hr = IEnumVARIANT_Skip(enumvar, 0);
966 ok(hr == S_OK, "got 0x%08x\n", hr);
968 hr = IEnumVARIANT_Reset(enumvar);
969 ok(hr == S_OK, "got 0x%08x\n", hr);
970 hr = IEnumVARIANT_Skip(enumvar, 1);
971 ok(hr == S_OK, "got 0x%08x\n", hr);
972 hr = IEnumVARIANT_Skip(enumvar, 1);
973 ok(hr == S_FALSE, "got 0x%08x\n", hr);
975 V_VT(&key) = VT_I2;
976 V_I2(&key) = 4000;
977 V_VT(&item) = VT_I4;
978 V_I4(&item) = 200;
979 hr = IDictionary_Add(dict, &key, &item);
980 ok(hr == S_OK, "got 0x%08x\n", hr);
982 V_VT(&key) = VT_I2;
983 V_I2(&key) = 0;
984 V_VT(&item) = VT_I4;
985 V_I4(&item) = 300;
986 hr = IDictionary_Add(dict, &key, &item);
987 ok(hr == S_OK, "got 0x%08x\n", hr);
989 hr = IEnumVARIANT_Reset(enumvar);
990 ok(hr == S_OK, "got 0x%08x\n", hr);
992 VariantInit(&key);
993 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
994 ok(hr == S_OK, "got 0x%08x\n", hr);
995 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
996 ok(V_I2(&key) == 1, "got %d\n", V_I2(&key));
997 ok(fetched == 1, "got %u\n", fetched);
999 hr = IEnumVARIANT_Reset(enumvar);
1000 ok(hr == S_OK, "got 0x%08x\n", hr);
1002 hr = IDictionary_Remove(dict, &key);
1003 ok(hr == S_OK, "got 0x%08x\n", hr);
1005 VariantInit(&key);
1006 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1007 ok(hr == S_OK, "got 0x%08x\n", hr);
1008 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
1009 ok(V_I2(&key) == 4000, "got %d\n", V_I2(&key));
1010 ok(fetched == 1, "got %u\n", fetched);
1012 VariantInit(&key);
1013 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1014 ok(hr == S_OK, "got 0x%08x\n", hr);
1015 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
1016 ok(V_I2(&key) == 0, "got %d\n", V_I2(&key));
1017 ok(fetched == 1, "got %u\n", fetched);
1019 /* enumeration reached the bottom, add one more pair */
1020 VariantInit(&key);
1021 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1022 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1024 V_VT(&key) = VT_I2;
1025 V_I2(&key) = 13;
1026 V_VT(&item) = VT_I4;
1027 V_I4(&item) = 350;
1028 hr = IDictionary_Add(dict, &key, &item);
1029 ok(hr == S_OK, "got 0x%08x\n", hr);
1031 /* still doesn't work until Reset() */
1032 VariantInit(&key);
1033 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1034 ok(hr == S_FALSE, "got 0x%08x\n", hr);
1036 IEnumVARIANT_Release(enumvar);
1037 IDictionary_Release(dict);
1040 START_TEST(dictionary)
1042 IDispatch *disp;
1043 HRESULT hr;
1045 CoInitialize(NULL);
1047 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1048 &IID_IDispatch, (void**)&disp);
1049 if(FAILED(hr)) {
1050 win_skip("Dictionary object is not supported: %08x\n", hr);
1051 CoUninitialize();
1052 return;
1054 IDispatch_Release(disp);
1056 test_interfaces();
1057 test_comparemode();
1058 test_hash_value();
1059 test_Exists();
1060 test_Keys();
1061 test_Remove();
1062 test_Item();
1063 test_Add();
1064 test_IEnumVARIANT();
1066 CoUninitialize();