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