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