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
29 #include "wine/test.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
;
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)
70 IObjectWithSite
*site
;
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
);
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
);
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
);
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");
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");
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
;
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
);
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 */
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
)
177 if (method
== TextCompare
|| method
== DatabaseCompare
)
178 ch
= PtrToInt(CharLowerW(IntToPtr(*str
)));
182 hash
+= (hash
<< 4) + ch
;
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;
204 unsigned int exp_bias
: 8;
205 unsigned int sign
: 1;
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;
222 static HRESULT WINAPI
test_unk_QI(IUnknown
*iface
, REFIID riid
, void **obj
)
224 if (IsEqualIID(riid
, &IID_IUnknown
)) {
229 ok(0, "unexpected %s\n", wine_dbgstr_guid(riid
));
231 return E_NOINTERFACE
;
234 static HRESULT WINAPI
test_unk_no_QI(IUnknown
*iface
, REFIID riid
, void **obj
)
237 return E_NOINTERFACE
;
240 static ULONG WINAPI
test_unk_AddRef(IUnknown
*iface
)
242 ok(0, "unexpected\n");
246 static ULONG WINAPI
test_unk_Release(IUnknown
*iface
)
251 static const IUnknownVtbl test_unk_vtbl
= {
257 static const IUnknownVtbl test_unk_no_vtbl
= {
263 static HRESULT WINAPI
test_disp_QI(IDispatch
*iface
, REFIID riid
, void **obj
)
265 if (IsEqualIID(riid
, &IID_IDispatch
) || IsEqualIID(riid
, &IID_IUnknown
)) {
270 ok(0, "unexpected %s\n", wine_dbgstr_guid(riid
));
272 return E_NOINTERFACE
;
275 static ULONG WINAPI
test_disp_AddRef(IDispatch
*iface
)
277 ok(0, "unexpected\n");
281 static ULONG WINAPI
test_disp_Release(IDispatch
*iface
)
286 static HRESULT WINAPI
test_disp_GetTypeInfoCount(IDispatch
*iface
, UINT
*count
)
288 ok(0, "unexpected call\n");
292 static HRESULT WINAPI
test_disp_GetTypeInfo(IDispatch
*iface
, UINT index
, LCID lcid
, ITypeInfo
**ti
)
294 ok(0, "unexpected call\n");
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");
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");
312 static const IDispatchVtbl test_disp_vtbl
= {
316 test_disp_GetTypeInfoCount
,
317 test_disp_GetTypeInfo
,
318 test_disp_GetIDsOfNames
,
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] =
339 static const int int_hash_tests
[] = {
343 static const FLOAT float_hash_tests
[] = {
344 0.0, -1.0, 100.0, 1.0, 255.0, 1.234
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
;
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
]);
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
),
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
]);
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
),
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
]);
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
),
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
;
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
));
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
));
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
));
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
));
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
++) {
467 expected
= get_num_hash(int_hash_tests
[i
]);
470 V_I2(&key
) = int_hash_tests
[i
];
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
),
478 i2
= int_hash_tests
[i
];
479 V_VT(&key
) = VT_I2
|VT_BYREF
;
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
),
489 V_I4(&key
) = int_hash_tests
[i
];
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
),
497 i4
= int_hash_tests
[i
];
498 V_VT(&key
) = VT_I4
|VT_BYREF
;
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
),
507 expected
= get_num_hash((FLOAT
)(BYTE
)int_hash_tests
[i
]);
509 V_UI1(&key
) = int_hash_tests
[i
];
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
),
517 ui1
= int_hash_tests
[i
];
518 V_VT(&key
) = VT_UI1
|VT_BYREF
;
519 V_UI1REF(&key
) = &ui1
;
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
),
530 fx4
.i
.exp_bias
= 0xff;
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
));
544 fx4
.i
.exp_bias
= 0xff;
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
));
556 fx8
.i
.exp_bias
= 0x7ff;
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
;
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
));
580 fx8
.i
.exp_bias
= 0x7ff;
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
;
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
++) {
603 expected
= get_num_hash(float_hash_tests
[i
]);
606 V_R4(&key
) = float_hash_tests
[i
];
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
),
614 flt
= float_hash_tests
[i
];
615 V_VT(&key
) = VT_R4
|VT_BYREF
;
616 V_R4REF(&key
) = &flt
;
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
),
625 V_R8(&key
) = float_hash_tests
[i
];
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
),
633 dbl
= float_hash_tests
[i
];
634 V_VT(&key
) = VT_R8
|VT_BYREF
;
635 V_R8REF(&key
) = &dbl
;
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
),
643 V_VT(&key
) = VT_DATE
;
644 V_DATE(&key
) = float_hash_tests
[i
];
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
),
652 V_VT(&key
) = VT_DATE
|VT_BYREF
;
653 date
= float_hash_tests
[i
];
654 V_DATEREF(&key
) = &date
;
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
),
663 /* interface pointers as keys */
664 V_VT(&key
) = VT_UNKNOWN
;
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
;
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
;
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
;
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
;
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
);
718 V_VT(&key
) = VT_UNKNOWN
|VT_BYREF
;
719 V_UNKNOWNREF(&key
) = &unk
;
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
;
729 V_UNKNOWNREF(&key
) = &unk
;
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
;
740 V_DISPATCHREF(&key
) = (IDispatch
**)&unk
;
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
;
750 V_DISPATCHREF(&key
) = &disp
;
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)
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
);
777 hr
= IDictionary_Exists(dict
, &key
, NULL
);
778 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
, "got 0x%08x\n", hr
);
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
);
788 hr
= IDictionary_Add(dict
, &key
, &item
);
789 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
793 hr
= IDictionary_Add(dict
, &key
, &item
);
794 ok(hr
== CTL_E_KEY_ALREADY_EXISTS
, "got 0x%08x\n", hr
);
798 hr
= IDictionary_Exists(dict
, &key
, NULL
);
799 ok(hr
== CTL_E_ILLEGALFUNCTIONCALL
, "got 0x%08x\n", hr
);
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 */
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
;
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
);
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
));
842 hr
= IDictionary_Add(dict
, &key
, &item
);
843 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
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
));
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
);
865 IDictionary_Release(dict
);
868 static void test_Remove(void)
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
);
879 hr
= IDictionary_Remove(dict
, NULL
);
881 /* nothing added yet */
884 hr
= IDictionary_Remove(dict
, &key
);
885 ok(hr
== CTL_E_ELEMENT_NOT_FOUND
, "got 0x%08x\n", hr
);
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)
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
);
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
));
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)
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");
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
));
950 IDictionary_Release(dict
);
953 static void test_IEnumVARIANT(void)
955 IUnknown
*enum1
, *enum2
;
956 IEnumVARIANT
*enumvar
;
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
);
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
);
1007 V_VT(&item
) = VT_I4
;
1009 hr
= IDictionary_Add(dict
, &key
, &item
);
1010 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1014 V_VT(&item
) = VT_I4
;
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
);
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
);
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
);
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 */
1051 hr
= IEnumVARIANT_Next(enumvar
, 1, &key
, &fetched
);
1052 ok(hr
== S_FALSE
, "got 0x%08x\n", hr
);
1056 V_VT(&item
) = VT_I4
;
1058 hr
= IDictionary_Add(dict
, &key
, &item
);
1059 ok(hr
== S_OK
, "got 0x%08x\n", hr
);
1061 /* still doesn't work until Reset() */
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
)
1077 hr
= CoCreateInstance(&CLSID_Dictionary
, NULL
, CLSCTX_INPROC_SERVER
|CLSCTX_INPROC_HANDLER
,
1078 &IID_IDispatch
, (void**)&disp
);
1080 win_skip("Dictionary object is not supported: %08x\n", hr
);
1084 IDispatch_Release(disp
);
1094 test_IEnumVARIANT();