ReactOS 0.4.17-dev-966-gf06eace
dictionary.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012 Alistair Leslie-Hughes
3 * Copyright 2015 Nikolay Sivov for CodeWeavers
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20#define COBJMACROS
21#include <stdio.h>
22
23#include "windows.h"
24#include "ole2.h"
25#include "oleauto.h"
26#include "olectl.h"
27#include "dispex.h"
28
29#include "wine/test.h"
30
31#include "scrrun.h"
32
33#define test_provideclassinfo(a, b) _test_provideclassinfo((IDispatch*)a, b, __LINE__)
34static void _test_provideclassinfo(IDispatch *disp, const GUID *guid, int line)
35{
37 TYPEATTR *attr;
38 ITypeInfo *ti;
39 IUnknown *unk;
40 HRESULT hr;
41
42 hr = IDispatch_QueryInterface(disp, &IID_IProvideClassInfo, (void **)&classinfo);
43 ok_(__FILE__,line) (hr == S_OK, "Failed to get IProvideClassInfo, %#lx.\n", hr);
44
45 hr = IProvideClassInfo_GetClassInfo(classinfo, &ti);
46 ok_(__FILE__,line) (hr == S_OK, "GetClassInfo() failed, %#lx.\n", hr);
47
48 hr = ITypeInfo_GetTypeAttr(ti, &attr);
49 ok_(__FILE__,line) (hr == S_OK, "GetTypeAttr() failed, %#lx.\n", hr);
50
51 ok_(__FILE__,line) (IsEqualGUID(&attr->guid, guid), "Unexpected typeinfo %s, expected %s\n", wine_dbgstr_guid(&attr->guid),
53
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);
58
59 IProvideClassInfo_Release(classinfo);
60 ITypeInfo_ReleaseTypeAttr(ti, attr);
61 ITypeInfo_Release(ti);
62}
63
64static void test_interfaces(void)
65{
66 HRESULT hr;
67 IDispatch *disp;
68 IDispatchEx *dispex;
69 IDictionary *dict;
72 VARIANT_BOOL exists;
73 LONG count = 0;
74
75 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
76 &IID_IDispatch, (void**)&disp);
77 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
78
81
82 hr = IDispatch_QueryInterface(disp, &IID_IDictionary, (void**)&dict);
83 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
84
85 hr = IDispatch_QueryInterface(disp, &IID_IObjectWithSite, (void**)&site);
86 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
87
88 hr = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
89 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
90
91 test_provideclassinfo(disp, &CLSID_Dictionary);
92
93 V_VT(&key) = VT_BSTR;
94 V_BSTR(&key) = SysAllocString(L"a");
95 V_VT(&value) = VT_BSTR;
97 hr = IDictionary_Add(dict, &key, &value);
98 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
100
101 exists = VARIANT_FALSE;
102 hr = IDictionary_Exists(dict, &key, &exists);
103 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
104 ok(exists == VARIANT_TRUE, "Expected TRUE but got FALSE.\n");
106
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, "Unexpected hr %#lx.\n", hr);
112 ok(exists == VARIANT_FALSE, "Expected FALSE but got TRUE.\n");
114
115 hr = IDictionary_get_Count(dict, &count);
116 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
117 ok(count == 1, "Unexpected value %lu.\n", count);
118
119 IDictionary_Release(dict);
120 IDispatch_Release(disp);
121}
122
123static void test_comparemode(void)
124{
125 CompareMethod method;
126 IDictionary *dict;
128 HRESULT hr;
129
130 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
131 &IID_IDictionary, (void**)&dict);
132 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
133
134 if (0) /* crashes on native */
135 hr = IDictionary_get_CompareMode(dict, NULL);
136
137 method = 10;
138 hr = IDictionary_get_CompareMode(dict, &method);
139 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
140 ok(method == BinaryCompare, "got %d\n", method);
141
142 /* invalid mode value is not checked */
143 hr = IDictionary_put_CompareMode(dict, 10);
144 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
145
146 hr = IDictionary_get_CompareMode(dict, &method);
147 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
148 ok(method == 10, "got %d\n", method);
149
150 hr = IDictionary_put_CompareMode(dict, DatabaseCompare);
151 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
152
153 hr = IDictionary_get_CompareMode(dict, &method);
154 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
155 ok(method == DatabaseCompare, "got %d\n", method);
156
157 /* try to change mode of a non-empty dict */
158 V_VT(&key) = VT_I2;
159 V_I2(&key) = 0;
161 hr = IDictionary_Add(dict, &key, &item);
162 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
163
164 hr = IDictionary_put_CompareMode(dict, BinaryCompare);
165 ok(hr == CTL_E_ILLEGALFUNCTIONCALL, "Unexpected hr %#lx.\n", hr);
166
167 IDictionary_Release(dict);
168}
169
170static DWORD get_str_hash(const WCHAR *str, CompareMethod method)
171{
172 DWORD hash = 0;
173
174 while (*str) {
175 WCHAR ch;
176
177 if (method == TextCompare || method == DatabaseCompare)
179 else
180 ch = *str;
181
182 hash += (hash << 4) + ch;
183 str++;
184 }
185
186 return hash % 1201;
187}
188
190{
191 return (*((DWORD*)&num)) % 1201;
192}
193
194static DWORD get_ptr_hash(void *ptr)
195{
197#ifdef _WIN64
198 hash ^= (ULONG_PTR)ptr >> 32;
199#endif
200 return hash % 1201;
201}
202
203typedef union
204{
205 struct
206 {
207 unsigned int m : 23;
208 unsigned int exp_bias : 8;
209 unsigned int sign : 1;
210 } i;
211 float f;
212} R4_FIELDS;
213
214typedef union
215{
216 struct
217 {
218 unsigned int m_lo : 32; /* 52 bits of precision */
219 unsigned int m_hi : 20;
220 unsigned int exp_bias : 11; /* bias == 1023 */
221 unsigned int sign : 1;
222 } i;
223 double d;
224} R8_FIELDS;
225
227{
229 *obj = iface;
230 return S_OK;
231 }
232
233 ok(0, "unexpected %s\n", wine_dbgstr_guid(riid));
234 *obj = NULL;
235 return E_NOINTERFACE;
236}
237
239{
240 *obj = NULL;
241 return E_NOINTERFACE;
242}
243
245{
246 return 2;
247}
248
250{
251 return 1;
252}
253
254static const IUnknownVtbl test_unk_vtbl = {
258};
259
260static const IUnknownVtbl test_unk_no_vtbl = {
264};
265
267{
269 *obj = iface;
270 return S_OK;
271 }
272
273 ok(0, "unexpected %s\n", wine_dbgstr_guid(riid));
274 *obj = NULL;
275 return E_NOINTERFACE;
276}
277
279{
280 ok(0, "unexpected\n");
281 return 2;
282}
283
285{
286 return 1;
287}
288
290{
291 ok(0, "unexpected call\n");
292 return E_NOTIMPL;
293}
294
296{
297 ok(0, "unexpected call\n");
298 return E_NOTIMPL;
299}
300
302 UINT name_count, LCID lcid, DISPID *dispid)
303{
304 ok(0, "unexpected call\n");
305 return E_NOTIMPL;
306}
307
309 LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *arg_err)
310{
311 ok(0, "unexpected call\n");
312 return E_NOTIMPL;
313}
314
315static const IDispatchVtbl test_disp_vtbl = {
323};
324
328
329static void test_hash_value(void)
330{
331 /* string test data */
332 static const WCHAR str_hash_tests[][10] =
333 {
334 L"abcd",
335 L"aBCd1",
336 L"123",
337 L"A",
338 L"a",
339 L""
340 };
341
342 static const int int_hash_tests[] = {
343 0, -1, 100, 1, 255
344 };
345
346 static const FLOAT float_hash_tests[] = {
347 0.0, -1.0, 100.0, 1.0, 255.0, 1.234, 2175.0, 6259.0
348 };
349
350 IDictionary *dict;
352 IDispatch *disp;
354 IUnknown *unk;
355 R8_FIELDS fx8;
356 R4_FIELDS fx4;
357 HRESULT hr;
358 unsigned i;
359
360 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
361 &IID_IDictionary, (void**)&dict);
362 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
363
364 V_VT(&key) = VT_BSTR;
365 V_BSTR(&key) = NULL;
367 hr = IDictionary_get_HashVal(dict, &key, &hash);
368 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
369 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
370 ok(!V_I4(&hash), "Unexpected hash %#lx.\n", V_I4(&hash));
371
372 for (i = 0; i < ARRAY_SIZE(str_hash_tests); ++i)
373 {
374 expected = get_str_hash(str_hash_tests[i], BinaryCompare);
375
376 hr = IDictionary_put_CompareMode(dict, BinaryCompare);
377 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
378
379 V_VT(&key) = VT_BSTR;
380 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
382 hr = IDictionary_get_HashVal(dict, &key, &hash);
383 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
384 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
385 ok(V_I4(&hash) == expected, "%d: db mode: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
387
388 expected = get_str_hash(str_hash_tests[i], TextCompare);
389 hr = IDictionary_put_CompareMode(dict, TextCompare);
390 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
391
392 V_VT(&key) = VT_BSTR;
393 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
395 hr = IDictionary_get_HashVal(dict, &key, &hash);
396 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
397 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
398 ok(V_I4(&hash) == expected, "%d: db mode: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
400
401 expected = get_str_hash(str_hash_tests[i], DatabaseCompare);
402 hr = IDictionary_put_CompareMode(dict, DatabaseCompare);
403 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
404
405 V_VT(&key) = VT_BSTR;
406 V_BSTR(&key) = SysAllocString(str_hash_tests[i]);
408 hr = IDictionary_get_HashVal(dict, &key, &hash);
409 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
410 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
411 ok(V_I4(&hash) == expected, "%d: db mode: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
413 }
414
415 V_VT(&key) = VT_INT;
416 V_INT(&key) = 1;
418 hr = IDictionary_get_HashVal(dict, &key, &hash);
419 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "Unexpected hr %#lx.\n", hr);
420 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
421 ok(V_I4(&hash) == ~0u, "Unexpected hash %#lx.\n", V_I4(&hash));
422
423 V_VT(&key) = VT_UINT;
424 V_UINT(&key) = 1;
426 hr = IDictionary_get_HashVal(dict, &key, &hash);
427 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "Unexpected hr %#lx.\n", hr);
428 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
429 ok(V_I4(&hash) == ~0u, "Unexpected hash %#lx.\n", V_I4(&hash));
430
431 V_VT(&key) = VT_I1;
432 V_I1(&key) = 1;
434 hr = IDictionary_get_HashVal(dict, &key, &hash);
435 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "Unexpected hr %#lx.\n", hr);
436 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
437 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0xa1), "Unexpected hash %#lx.\n", V_I4(&hash));
438
439 V_VT(&key) = VT_I8;
440 V_I8(&key) = 1;
442 hr = IDictionary_get_HashVal(dict, &key, &hash);
443 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "Unexpected hr %#lx.\n", hr);
444 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
445 ok(V_I4(&hash) == ~0u, "Unexpected hash %#lx.\n", V_I4(&hash));
446
447 V_VT(&key) = VT_UI2;
448 V_UI2(&key) = 1;
450 hr = IDictionary_get_HashVal(dict, &key, &hash);
451 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "Unexpected hr %#lx.\n", hr);
452 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
453 ok(V_I4(&hash) == ~0u, "Unexpected hash %#lx.\n", V_I4(&hash));
454
455 V_VT(&key) = VT_UI4;
456 V_UI4(&key) = 1;
458 hr = IDictionary_get_HashVal(dict, &key, &hash);
459 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "Unexpected hr %#lx.\n", hr);
460 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
461 ok(V_I4(&hash) == ~0u, "Unexpected hash %#lx.\n", V_I4(&hash));
462
463 for (i = 0; i < ARRAY_SIZE(int_hash_tests); i++) {
464 SHORT i2;
465 BYTE ui1;
466 LONG i4;
467
468 expected = get_num_hash(int_hash_tests[i]);
469
470 V_VT(&key) = VT_I2;
471 V_I2(&key) = int_hash_tests[i];
473 hr = IDictionary_get_HashVal(dict, &key, &hash);
474 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
475 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
476 ok(V_I4(&hash) == expected, "%d: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
477
478 i2 = int_hash_tests[i];
480 V_I2REF(&key) = &i2;
482 hr = IDictionary_get_HashVal(dict, &key, &hash);
483 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
484 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
485 ok(V_I4(&hash) == expected, "%d: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
486
487 V_VT(&key) = VT_I4;
488 V_I4(&key) = int_hash_tests[i];
490 hr = IDictionary_get_HashVal(dict, &key, &hash);
491 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
492 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
493 ok(V_I4(&hash) == expected, "%d: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
494
495 i4 = int_hash_tests[i];
497 V_I4REF(&key) = &i4;
499 hr = IDictionary_get_HashVal(dict, &key, &hash);
500 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
501 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
502 ok(V_I4(&hash) == expected, "%d: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
503
504 expected = get_num_hash((FLOAT)(BYTE)int_hash_tests[i]);
505 V_VT(&key) = VT_UI1;
506 V_UI1(&key) = int_hash_tests[i];
508 hr = IDictionary_get_HashVal(dict, &key, &hash);
509 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
510 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
511 ok(V_I4(&hash) == expected, "%d: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
512
513 ui1 = int_hash_tests[i];
515 V_UI1REF(&key) = &ui1;
517 hr = IDictionary_get_HashVal(dict, &key, &hash);
518 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
519 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
520 ok(V_I4(&hash) == expected, "%d: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
521 }
522
523 /* nan */
524 fx4.f = 10.0;
525 fx4.i.exp_bias = 0xff;
526
527 V_VT(&key) = VT_R4;
528 V_R4(&key) = fx4.f;
530 hr = IDictionary_get_HashVal(dict, &key, &hash);
531 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "Unexpected hr %#lx.\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 */), "Unexpected hr %#lx.\n", V_I4(&hash));
535
536 /* inf */
537 fx4.f = 10.0;
538 fx4.i.m = 0;
539 fx4.i.exp_bias = 0xff;
540
541 V_VT(&key) = VT_R4;
542 V_R4(&key) = fx4.f;
543 V_I4(&hash) = 10;
544 hr = IDictionary_get_HashVal(dict, &key, &hash);
545 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
546 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
547 ok(!V_I4(&hash), "Unexpected hash %#lx.\n", V_I4(&hash));
548
549 /* nan */
550 fx8.d = 10.0;
551 fx8.i.exp_bias = 0x7ff;
552
553 V_VT(&key) = VT_R8;
554 V_R8(&key) = fx8.d;
556 hr = IDictionary_get_HashVal(dict, &key, &hash);
557 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "Unexpected hr %#lx.\n", hr);
558 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
559 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ ||
560 V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "Unexpected hash %#lx.\n", V_I4(&hash));
561
562 V_VT(&key) = VT_DATE;
563 V_DATE(&key) = fx8.d;
565 hr = IDictionary_get_HashVal(dict, &key, &hash);
566 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k, win2k3 */, "Unexpected hr %#lx.\n", hr);
567 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
568 ok(V_I4(&hash) == ~0u || broken(V_I4(&hash) == 0 /* win2k */ ||
569 V_I4(&hash) == 0x1f4 /* vista, win2k8 */), "Unexpected hash %#lx.\n", V_I4(&hash));
570
571 /* inf */
572 fx8.d = 10.0;
573 fx8.i.m_lo = 0;
574 fx8.i.m_hi = 0;
575 fx8.i.exp_bias = 0x7ff;
576
577 V_VT(&key) = VT_R8;
578 V_R8(&key) = fx8.d;
579 V_I4(&hash) = 10;
580 hr = IDictionary_get_HashVal(dict, &key, &hash);
581 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
582 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
583 ok(!V_I4(&hash), "Unexpected hash %#lx.\n", V_I4(&hash));
584
585 V_VT(&key) = VT_DATE;
586 V_DATE(&key) = fx8.d;
587 V_I4(&hash) = 10;
588 hr = IDictionary_get_HashVal(dict, &key, &hash);
589 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
590 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
591 ok(!V_I4(&hash), "Unexpected hash %#lx.\n", V_I4(&hash));
592
593 for (i = 0; i < ARRAY_SIZE(float_hash_tests); i++) {
594 double dbl;
595 FLOAT flt;
596 DATE date;
597
598 expected = get_num_hash(float_hash_tests[i]);
599
600 V_VT(&key) = VT_R4;
601 V_R4(&key) = float_hash_tests[i];
603 hr = IDictionary_get_HashVal(dict, &key, &hash);
604 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
605 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
606 ok(V_I4(&hash) == expected, "%d: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
607
608 flt = float_hash_tests[i];
610 V_R4REF(&key) = &flt;
612 hr = IDictionary_get_HashVal(dict, &key, &hash);
613 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
614 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
615 ok(V_I4(&hash) == expected, "%d: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
616
617 V_VT(&key) = VT_R8;
618 V_R8(&key) = float_hash_tests[i];
620 hr = IDictionary_get_HashVal(dict, &key, &hash);
621 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
622 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
623 ok(V_I4(&hash) == expected, "%d: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
624
625 dbl = float_hash_tests[i];
627 V_R8REF(&key) = &dbl;
629 hr = IDictionary_get_HashVal(dict, &key, &hash);
630 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
631 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
632 ok(V_I4(&hash) == expected, "%d: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
633
634 V_VT(&key) = VT_DATE;
635 V_DATE(&key) = float_hash_tests[i];
637 hr = IDictionary_get_HashVal(dict, &key, &hash);
638 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
639 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
640 ok(V_I4(&hash) == expected, "%d: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
641
643 date = float_hash_tests[i];
644 V_DATEREF(&key) = &date;
646 hr = IDictionary_get_HashVal(dict, &key, &hash);
647 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
648 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
649 ok(V_I4(&hash) == expected, "%d: got hash %#lx, expected %#lx.\n", i, V_I4(&hash), expected);
650 }
651
652 /* interface pointers as keys */
653 V_VT(&key) = VT_UNKNOWN;
654 V_UNKNOWN(&key) = 0;
656 V_I4(&hash) = 1;
657 hr = IDictionary_get_HashVal(dict, &key, &hash);
658 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
659 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
660 ok(!V_I4(&hash), "Unexpected hash %#lx.\n", V_I4(&hash));
661
662 /* QI doesn't work */
663 V_VT(&key) = VT_UNKNOWN;
667 hr = IDictionary_get_HashVal(dict, &key, &hash);
668 ok(hr == CTL_E_ILLEGALFUNCTIONCALL || broken(hr == S_OK) /* win2k */, "Unexpected hr %#lx.\n", hr);
669 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
670 ok(V_I4(&hash) == ~0u, "Unexpected hash %#lx.\n", V_I4(&hash));
671
672 V_VT(&key) = VT_UNKNOWN;
676 hr = IDictionary_get_HashVal(dict, &key, &hash);
677 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
678 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
679 ok(V_I4(&hash) == expected, "got hash %#lx, expected %#lx\n", V_I4(&hash), expected);
680
681 /* interface without IDispatch support */
682 V_VT(&key) = VT_DISPATCH;
686 hr = IDictionary_get_HashVal(dict, &key, &hash);
687 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
688 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
689 ok(V_I4(&hash) == expected, "got hash %#lx, expected %#lx\n", V_I4(&hash), expected);
690
691 V_VT(&key) = VT_DISPATCH;
695 hr = IDictionary_get_HashVal(dict, &key, &hash);
696 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
697 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
698 ok(V_I4(&hash) == expected, "got hash %#lx, expected %#lx\n", V_I4(&hash), expected);
699
700 /* same with BYREF */
701if (0) { /* crashes on native */
703 V_UNKNOWNREF(&key) = 0;
704 hr = IDictionary_get_HashVal(dict, &key, &hash);
705}
706 unk = NULL;
708 V_UNKNOWNREF(&key) = &unk;
710 V_I4(&hash) = 1;
711 hr = IDictionary_get_HashVal(dict, &key, &hash);
712 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
713 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
714 ok(!V_I4(&hash), "Unexpected hash %#lx.\n", V_I4(&hash));
715
717 unk = &test_unk;
718 V_UNKNOWNREF(&key) = &unk;
721 hr = IDictionary_get_HashVal(dict, &key, &hash);
722 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
723 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
724 ok(V_I4(&hash) == expected, "got hash %#lx, expected %#lx\n", V_I4(&hash), expected);
725
726 /* interface without IDispatch support */
728 unk = &test_unk;
729 V_DISPATCHREF(&key) = (IDispatch**)&unk;
732 hr = IDictionary_get_HashVal(dict, &key, &hash);
733 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
734 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
735 ok(V_I4(&hash) == expected, "got hash %#lx, expected %#lx\n", V_I4(&hash), expected);
736
738 disp = &test_disp;
739 V_DISPATCHREF(&key) = &disp;
742 hr = IDictionary_get_HashVal(dict, &key, &hash);
743 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
744 ok(V_VT(&hash) == VT_I4, "got %d\n", V_VT(&hash));
745 ok(V_I4(&hash) == expected, "got hash %#lx, expected %#lx\n", V_I4(&hash), expected);
746
747 V_VT(&key) = VT_EMPTY;
748 V_I4(&key) = 1234;
749 V_I4(&hash) = 5678;
750 hr = IDictionary_get_HashVal(dict, &key, &hash);
751 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
752 ok(V_VT(&hash) == VT_I4, "Unexpected hash type %d.\n", V_VT(&hash));
753 ok(V_I4(&hash) == 0, "Unexpected hash value %ld.\n", V_I4(&hash));
754
755 V_VT(&key) = VT_NULL;
756 V_I4(&key) = 1234;
757 V_I4(&hash) = 5678;
758 hr = IDictionary_get_HashVal(dict, &key, &hash);
759 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
760 ok(V_VT(&hash) == VT_I4, "Unexpected hash type %d.\n", V_VT(&hash));
761 ok(V_I4(&hash) == 0, "Unexpected hash value %ld.\n", V_I4(&hash));
762
763 IDictionary_Release(dict);
764}
765
766static void test_Exists(void)
767{
768 VARIANT_BOOL exists;
769 IDictionary *dict;
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, "Unexpected hr %#lx.\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, "Unexpected hr %#lx.\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, "Unexpected hr %#lx.\n", hr);
790 ok(exists == VARIANT_FALSE, "got %x\n", exists);
791
793 hr = IDictionary_Add(dict, &key, &item);
794 ok(hr == S_OK, "Unexpected hr %#lx.\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, "Unexpected hr %#lx.\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, "Unexpected hr %#lx.\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, "Unexpected hr %#lx.\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, "Unexpected hr %#lx.\n", hr);
819 ok(exists == VARIANT_TRUE, "got %x\n", exists);
820
821 IDictionary_Release(dict);
822}
823
824static void test_Keys(void)
825{
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, "Unexpected hr %#lx.\n", hr);
834
835 hr = IDictionary_Keys(dict, NULL);
836 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
837
839 hr = IDictionary_Keys(dict, &keys);
840 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
841 ok(V_VT(&keys) == (VT_ARRAY|VT_VARIANT), "got %d\n", V_VT(&keys));
843
844 V_VT(&key) = VT_R4;
845 V_R4(&key) = 0.0;
847 hr = IDictionary_Add(dict, &key, &item);
848 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
849
851 hr = IDictionary_Keys(dict, &keys);
852 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
853 ok(V_VT(&keys) == (VT_ARRAY|VT_VARIANT), "got %d\n", V_VT(&keys));
854
856 index = 0;
858 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
859 ok(V_VT(&key) == VT_R4, "got %d\n", V_VT(&key));
860
862 ok(index == 1, "Unexpected value %ld.\n", index);
863
865 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
866 ok(index == 0, "Unexpected value %ld.\n", index);
867
869
870 hr = IDictionary_RemoveAll(dict);
871 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
872
873 /* Integer key type. */
874 V_VT(&key) = VT_I4;
875 V_I4(&key) = 0;
877 hr = IDictionary_Add(dict, &key, &item);
878 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
879
881 hr = IDictionary_Keys(dict, &keys);
882 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
883 ok(V_VT(&keys) == (VT_ARRAY|VT_VARIANT), "got %d\n", V_VT(&keys));
884
886 index = 0;
888 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
889 ok(V_VT(&key) == VT_I4, "got %d\n", V_VT(&key));
890
892
893 IDictionary_Release(dict);
894}
895
896static void test_Remove(void)
897{
899 IDictionary *dict;
900 HRESULT hr;
901
902 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
903 &IID_IDictionary, (void**)&dict);
904 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
905
906 if (0)
907 hr = IDictionary_Remove(dict, NULL);
908
909 /* nothing added yet */
910 V_VT(&key) = VT_R4;
911 V_R4(&key) = 0.0;
912 hr = IDictionary_Remove(dict, &key);
913 ok(hr == CTL_E_ELEMENT_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
914
916 hr = IDictionary_Add(dict, &key, &item);
917 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
918
919 hr = IDictionary_Remove(dict, &key);
920 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
921
922 IDictionary_Release(dict);
923}
924
925static void test_Item(void)
926{
928 IDictionary *dict;
929 HRESULT hr;
930
931 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
932 &IID_IDictionary, (void**)&dict);
933 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
934
935 V_VT(&key) = VT_I2;
936 V_I2(&key) = 10;
937 V_VT(&item) = VT_I2;
938 V_I2(&item) = 123;
939 hr = IDictionary_get_Item(dict, &key, &item);
940 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
941 ok(V_VT(&item) == VT_EMPTY, "got %d\n", V_VT(&item));
942
943 V_VT(&key) = VT_I2;
944 V_I2(&key) = 10;
945 V_VT(&item) = VT_I2;
946 hr = IDictionary_get_Item(dict, &key, &item);
947 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
948 ok(V_VT(&item) == VT_EMPTY, "got %d\n", V_VT(&item));
949
950 IDictionary_Release(dict);
951}
952
953static void test_Add(void)
954{
955 VARIANT item, key1, key2, hash1, hash2;
956 IDictionary *dict;
957 HRESULT hr;
958 BSTR str;
959
960 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
961 &IID_IDictionary, (void**)&dict);
962 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
963
964 str = SysAllocString(L"testW");
965 V_VT(&key1) = VT_I2;
966 V_I2(&key1) = 1;
968 V_BSTRREF(&item) = &str;
969 hr = IDictionary_Add(dict, &key1, &item);
970 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
971
972 hr = IDictionary_get_Item(dict, &key1, &item);
973 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
974 ok(V_VT(&item) == VT_BSTR, "got %d\n", V_VT(&item));
975
977
978 /* Items with matching key hashes, float keys. */
979 V_VT(&key1) = VT_R4;
980 V_R4(&key1) = 2175.0;
981
982 V_VT(&key2) = VT_R4;
983 V_R4(&key2) = 6259.0;
984
985 VariantInit(&hash1);
986 hr = IDictionary_get_HashVal(dict, &key1, &hash1);
987 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
988 VariantInit(&hash2);
989 hr = IDictionary_get_HashVal(dict, &key1, &hash2);
990 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
991 ok(V_VT(&hash1) == VT_I4, "Unexpected type %d.\n", V_VT(&hash1));
992 ok(V_VT(&hash2) == VT_I4, "Unexpected type %d.\n", V_VT(&hash2));
993 ok(V_I4(&hash1) == V_I4(&hash2), "Unexpected hash %#lx.\n", V_I4(&hash1));
994
995 V_VT(&item) = VT_BSTR;
996 V_BSTR(&item) = SysAllocString(L"float1");
997
998 hr = IDictionary_Add(dict, &key1, &item);
999 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1000 hr = IDictionary_Add(dict, &key2, &item);
1001 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1002
1003 V_VT(&key1) = VT_I4;
1004 V_I4(&key1) = 2175;
1005
1006 hr = IDictionary_Add(dict, &key1, &item);
1007 ok(hr == CTL_E_KEY_ALREADY_EXISTS, "Unexpected hr %#lx.\n", hr);
1008
1010
1011 /* Empty and null keys. */
1012 hr = IDictionary_RemoveAll(dict);
1013 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1014
1015 V_VT(&key1) = VT_EMPTY;
1016 V_I4(&key1) = 1;
1017
1018 V_VT(&item) = VT_BSTR;
1019 V_BSTR(&item) = SysAllocString(L"empty");
1020
1021 hr = IDictionary_Add(dict, &key1, &item);
1022 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1023
1024 V_VT(&key2) = VT_EMPTY;
1025 V_I4(&key2) = 2;
1026
1027 hr = IDictionary_Add(dict, &key2, &item);
1028 ok(hr == CTL_E_KEY_ALREADY_EXISTS, "Unexpected hr %#lx.\n", hr);
1029
1030 V_VT(&key2) = VT_NULL;
1031 V_I4(&key2) = 2;
1032
1033 hr = IDictionary_Add(dict, &key2, &item);
1034 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1035
1036 hr = IDictionary_RemoveAll(dict);
1037 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1038
1039 hr = IDictionary_Add(dict, &key2, &item);
1040 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1041
1042 hr = IDictionary_Add(dict, &key2, &item);
1043 ok(hr == CTL_E_KEY_ALREADY_EXISTS, "Unexpected hr %#lx.\n", hr);
1044
1045 hr = IDictionary_Add(dict, &key1, &item);
1046 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1047
1049
1050 IDictionary_Release(dict);
1051}
1052
1053static void test_IEnumVARIANT(void)
1054{
1055 IUnknown *enum1, *enum2;
1057 VARIANT key, item;
1058 IDictionary *dict;
1059 ULONG fetched;
1060 HRESULT hr;
1061
1062 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1063 &IID_IDictionary, (void**)&dict);
1064 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1065
1066 if (0) /* crashes on native */
1067 hr = IDictionary__NewEnum(dict, NULL);
1068
1069 hr = IDictionary__NewEnum(dict, &enum1);
1070 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1071
1072 hr = IDictionary__NewEnum(dict, &enum2);
1073 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1074 ok(enum1 != enum2, "got %p, %p\n", enum2, enum1);
1075 IUnknown_Release(enum2);
1076
1077 hr = IUnknown_QueryInterface(enum1, &IID_IEnumVARIANT, (void**)&enumvar);
1078 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1079 IUnknown_Release(enum1);
1080
1081 /* dictionary is empty */
1082 hr = IEnumVARIANT_Skip(enumvar, 1);
1083 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1084
1085 hr = IEnumVARIANT_Skip(enumvar, 0);
1086 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1087
1088 V_VT(&key) = VT_I2;
1089 V_I2(&key) = 1;
1090 V_VT(&item) = VT_I4;
1091 V_I4(&item) = 100;
1092 hr = IDictionary_Add(dict, &key, &item);
1093 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1094
1095 hr = IEnumVARIANT_Skip(enumvar, 0);
1096 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1097
1098 hr = IEnumVARIANT_Reset(enumvar);
1099 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1100 hr = IEnumVARIANT_Skip(enumvar, 1);
1101 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1102 hr = IEnumVARIANT_Skip(enumvar, 1);
1103 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1104
1105 V_VT(&key) = VT_I2;
1106 V_I2(&key) = 4000;
1107 V_VT(&item) = VT_I4;
1108 V_I4(&item) = 200;
1109 hr = IDictionary_Add(dict, &key, &item);
1110 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1111
1112 V_VT(&key) = VT_I2;
1113 V_I2(&key) = 0;
1114 V_VT(&item) = VT_I4;
1115 V_I4(&item) = 300;
1116 hr = IDictionary_Add(dict, &key, &item);
1117 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1118
1119 hr = IEnumVARIANT_Reset(enumvar);
1120 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1121
1122 VariantInit(&key);
1123 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1124 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1125 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
1126 ok(V_I2(&key) == 1, "got %d\n", V_I2(&key));
1127 ok(fetched == 1, "Unexpected value %lu.\n", fetched);
1128
1129 hr = IEnumVARIANT_Reset(enumvar);
1130 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1131
1132 hr = IDictionary_Remove(dict, &key);
1133 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1134
1135 VariantInit(&key);
1136 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1137 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1138 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
1139 ok(V_I2(&key) == 4000, "got %d\n", V_I2(&key));
1140 ok(fetched == 1, "Unexpected value %lu.\n", fetched);
1141
1142 VariantInit(&key);
1143 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1144 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1145 ok(V_VT(&key) == VT_I2, "got %d\n", V_VT(&key));
1146 ok(V_I2(&key) == 0, "got %d\n", V_I2(&key));
1147 ok(fetched == 1, "Unexpected value %lu.\n", fetched);
1148
1149 /* enumeration reached the bottom, add one more pair */
1150 VariantInit(&key);
1151 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1152 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1153
1154 V_VT(&key) = VT_I2;
1155 V_I2(&key) = 13;
1156 V_VT(&item) = VT_I4;
1157 V_I4(&item) = 350;
1158 hr = IDictionary_Add(dict, &key, &item);
1159 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1160
1161 /* still doesn't work until Reset() */
1162 VariantInit(&key);
1163 hr = IEnumVARIANT_Next(enumvar, 1, &key, &fetched);
1164 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1165
1166 IEnumVARIANT_Release(enumvar);
1167 IDictionary_Release(dict);
1168}
1169
1170static void test_putref_Item(void)
1171{
1172 IUnknown *obj = &test_unk;
1174 IDictionary *dict;
1175 HRESULT hr;
1176
1177 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1178 &IID_IDictionary, (void **)&dict);
1179 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1180
1181 V_VT(&key) = VT_I2;
1182 V_I2(&key) = 10;
1183 V_VT(&item) = VT_UNKNOWN;
1184 V_UNKNOWN(&item) = obj;
1185 hr = IDictionary_putref_Item(dict, &key, &item);
1186 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1187
1189 hr = IDictionary_get_Item(dict, &key, &item2);
1190 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1191 ok(V_VT(&item2) == VT_UNKNOWN, "Unexpected type.\n");
1192 ok(V_UNKNOWN(&item2) == obj, "Unexpected value.\n");
1194
1195 V_VT(&key) = VT_I2;
1196 V_I2(&key) = 11;
1198 V_UNKNOWNREF(&item) = &obj;
1199 hr = IDictionary_putref_Item(dict, &key, &item);
1200 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1201 hr = IDictionary_get_Item(dict, &key, &item2);
1202 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1203 ok(V_VT(&item2) == VT_UNKNOWN, "Unexpected type.\n");
1204 ok(V_UNKNOWN(&item2) == obj, "Unexpected value.\n");
1205
1206 IDictionary_Release(dict);
1207}
1208
1210{
1211 IDispatch *disp;
1212 HRESULT hr;
1213
1215
1216 hr = CoCreateInstance(&CLSID_Dictionary, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
1217 &IID_IDispatch, (void**)&disp);
1218 if(FAILED(hr)) {
1219 win_skip("Dictionary object is not supported: hr %#lx.\n", hr);
1221 return;
1222 }
1223 IDispatch_Release(disp);
1224
1228 test_Exists();
1229 test_Keys();
1230 test_Remove();
1231 test_Item();
1232 test_Add();
1235
1237}
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define TextCompare
Definition: text.h:19
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:20
#define PtrToInt(p)
Definition: basetsd.h:80
#define IntToPtr(i)
Definition: basetsd.h:83
const GUID IID_IUnknown
#define E_NOTIMPL
Definition: ddrawi.h:99
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: combase.c:2842
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
double DATE
Definition: compat.h:2253
OLECHAR * BSTR
Definition: compat.h:2293
short VARIANT_BOOL
Definition: compat.h:2290
@ VT_BSTR
Definition: compat.h:2303
@ VT_INT
Definition: compat.h:2316
@ VT_R4
Definition: compat.h:2299
@ VT_NULL
Definition: compat.h:2296
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_BYREF
Definition: compat.h:2342
@ VT_UI2
Definition: compat.h:2312
@ VT_ARRAY
Definition: compat.h:2341
@ VT_R8
Definition: compat.h:2300
@ VT_VARIANT
Definition: compat.h:2307
@ VT_I8
Definition: compat.h:2314
@ VT_I1
Definition: compat.h:2310
@ VT_I4
Definition: compat.h:2298
@ VT_DATE
Definition: compat.h:2302
@ VT_I2
Definition: compat.h:2297
@ VT_UI4
Definition: compat.h:2313
@ VT_UINT
Definition: compat.h:2317
@ VT_EMPTY
Definition: compat.h:2295
@ VT_DISPATCH
Definition: compat.h:2304
@ VT_UI1
Definition: compat.h:2311
LCID lcid
Definition: locale.c:5660
const UINT * keys
Definition: locale.c:418
LPWSTR WINAPI CharLowerW(WCHAR *str)
Definition: string.c:1136
GUID guid
Definition: version.c:147
unsigned char ch[4][2]
Definition: console.c:118
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:531
HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
Definition: safearray.c:1033
HRESULT WINAPI SafeArrayGetElement(SAFEARRAY *psa, LONG *rgIndices, void *pvData)
Definition: safearray.c:947
UINT WINAPI SafeArrayGetDim(SAFEARRAY *psa)
Definition: safearray.c:1094
static DWORD get_str_hash(const WCHAR *str, CompareMethod method)
Definition: dictionary.c:822
static DWORD get_num_hash(FLOAT num)
Definition: dictionary.c:840
static DWORD get_ptr_hash(void *ptr)
Definition: dictionary.c:861
method
Definition: dragdrop.c:54
#define L(x)
Definition: resources.c:13
#define ULONG_PTR
Definition: config.h:101
#define PtrToUlong(u)
Definition: config.h:107
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint * names
Definition: glext.h:11545
GLuint index
Definition: glext.h:6031
GLenum const GLfloat * params
Definition: glext.h:5645
GLbitfield flags
Definition: glext.h:7161
GLuint64EXT * result
Definition: glext.h:11304
GLuint64EXT GLuint GLuint GLenum GLenum GLuint GLuint GLenum GLuint GLuint key1
Definition: glext.h:10608
GLuint GLuint num
Definition: glext.h:9618
const GLfloat * m
Definition: glext.h:10848
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
unsigned int UINT
Definition: sysinfo.c:13
REFIID riid
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define d
Definition: ke_i.h:81
#define f
Definition: ke_i.h:83
#define sign(x)
Definition: mapdesc.cc:613
#define win_skip
Definition: minitest.h:67
__u16 date
Definition: mkdosfs.c:8
static PVOID ptr
Definition: dispmode.c:27
const IID IID_IObjectWithSite
BOOL expected
Definition: store.c:2000
static IActiveScriptSite * site
Definition: script.c:149
static EXCEPINFO excepinfo
Definition: automation.c:47
#define test_provideclassinfo(a, b)
Definition: dictionary.c:33
static void test_hash_value(void)
Definition: dictionary.c:329
static HRESULT WINAPI test_unk_no_QI(IUnknown *iface, REFIID riid, void **obj)
Definition: dictionary.c:238
static void test_comparemode(void)
Definition: dictionary.c:123
static IUnknown test_unk2
Definition: dictionary.c:326
static void test_Exists(void)
Definition: dictionary.c:766
static void test_interfaces(void)
Definition: dictionary.c:64
static void test_Remove(void)
Definition: dictionary.c:896
static void test_Keys(void)
Definition: dictionary.c:824
static void test_Item(void)
Definition: dictionary.c:925
static IDispatch test_disp
Definition: dictionary.c:327
static IUnknown test_unk
Definition: dictionary.c:325
static ULONG WINAPI test_disp_AddRef(IDispatch *iface)
Definition: dictionary.c:278
static HRESULT WINAPI test_disp_GetTypeInfo(IDispatch *iface, UINT index, LCID lcid, ITypeInfo **ti)
Definition: dictionary.c:295
static HRESULT WINAPI test_disp_QI(IDispatch *iface, REFIID riid, void **obj)
Definition: dictionary.c:266
static ULONG WINAPI test_disp_Release(IDispatch *iface)
Definition: dictionary.c:284
static ULONG WINAPI test_unk_AddRef(IUnknown *iface)
Definition: dictionary.c:244
static void _test_provideclassinfo(IDispatch *disp, const GUID *guid, int line)
Definition: dictionary.c:34
static void test_Add(void)
Definition: dictionary.c:953
static HRESULT WINAPI test_disp_Invoke(IDispatch *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *arg_err)
Definition: dictionary.c:308
static HRESULT WINAPI test_disp_GetTypeInfoCount(IDispatch *iface, UINT *count)
Definition: dictionary.c:289
static HRESULT WINAPI test_disp_GetIDsOfNames(IDispatch *iface, REFIID riid, LPOLESTR *names, UINT name_count, LCID lcid, DISPID *dispid)
Definition: dictionary.c:301
static const IUnknownVtbl test_unk_vtbl
Definition: dictionary.c:254
static void test_putref_Item(void)
Definition: dictionary.c:1170
static void test_IEnumVARIANT(void)
Definition: dictionary.c:1053
static HRESULT WINAPI test_unk_QI(IUnknown *iface, REFIID riid, void **obj)
Definition: dictionary.c:226
static ULONG WINAPI test_unk_Release(IUnknown *iface)
Definition: dictionary.c:249
static const IDispatchVtbl test_disp_vtbl
Definition: dictionary.c:315
static const IUnknownVtbl test_unk_no_vtbl
Definition: dictionary.c:260
static VARIANTARG static DISPID
Definition: ordinal.c:49
static const struct metadata_item item2[]
Definition: metadata.c:3608
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:240
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:273
#define V_UI1(A)
Definition: oleauto.h:266
#define V_I8(A)
Definition: oleauto.h:249
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_INT(A)
Definition: oleauto.h:251
#define V_BSTRREF(A)
Definition: oleauto.h:227
#define V_R4REF(A)
Definition: oleauto.h:261
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define V_UNKNOWNREF(A)
Definition: oleauto.h:282
#define V_UI2(A)
Definition: oleauto.h:268
#define V_I1(A)
Definition: oleauto.h:243
#define V_VT(A)
Definition: oleauto.h:211
#define V_DISPATCHREF(A)
Definition: oleauto.h:240
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_DATEREF(A)
Definition: oleauto.h:232
#define V_I4(A)
Definition: oleauto.h:247
#define V_R4(A)
Definition: oleauto.h:260
#define V_UINT(A)
Definition: oleauto.h:264
#define V_UI4(A)
Definition: oleauto.h:270
#define V_DISPATCH(A)
Definition: oleauto.h:239
#define V_R8(A)
Definition: oleauto.h:262
#define V_I2REF(A)
Definition: oleauto.h:246
#define V_DATE(A)
Definition: oleauto.h:231
#define V_UI1REF(A)
Definition: oleauto.h:267
#define V_R8REF(A)
Definition: oleauto.h:263
#define V_I2(A)
Definition: oleauto.h:245
#define V_I4REF(A)
Definition: oleauto.h:248
#define CTL_E_ILLEGALFUNCTIONCALL
Definition: olectl.h:267
const GUID IID_IProvideClassInfo
const GUID IID_IDispatch
short WCHAR
Definition: pedump.c:58
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
const WCHAR * str
DWORD LCID
Definition: nls.h:13
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:181
Definition: cookie.c:202
Definition: copy.c:22
Definition: parser.c:49
float FLOAT
Definition: typedefs.h:69
uint32_t ULONG
Definition: typedefs.h:59
struct R4_FIELDS::@648 i
float f
Definition: vartype.c:5444
double d
Definition: vartype.c:5504
struct R8_FIELDS::@649 i
Definition: pdh_main.c:64
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:626
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:547
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
#define E_NOINTERFACE
Definition: winerror.h:3479
unsigned char BYTE
Definition: xxhash.c:193