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__) 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 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 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 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 195 static DWORD get_num_hash(FLOAT num) 196 { 197 return (*((DWORD*)&num)) % 1201; 198 } 199 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 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 240 static HRESULT WINAPI test_unk_no_QI(IUnknown *iface, REFIID riid, void **obj) 241 { 242 *obj = NULL; 243 return E_NOINTERFACE; 244 } 245 246 static ULONG WINAPI test_unk_AddRef(IUnknown *iface) 247 { 248 ok(0, "unexpected\n"); 249 return 2; 250 } 251 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 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 281 static ULONG WINAPI test_disp_AddRef(IDispatch *iface) 282 { 283 ok(0, "unexpected\n"); 284 return 2; 285 } 286 287 static ULONG WINAPI test_disp_Release(IDispatch *iface) 288 { 289 return 1; 290 } 291 292 static HRESULT WINAPI test_disp_GetTypeInfoCount(IDispatch *iface, UINT *count) 293 { 294 ok(0, "unexpected call\n"); 295 return E_NOTIMPL; 296 } 297 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 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 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 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 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 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 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 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 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 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 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