1 /* 2 * Object Linking and Embedding Tests 3 * 4 * Copyright 2005 Robert Shearman 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include "precomp.h" 22 23 #ifndef __REACTOS__ 24 #include "initguid.h" 25 26 DEFINE_GUID(CLSID_Picture_Metafile,0x315,0,0,0xc0,0,0,0,0,0,0,0x46); 27 DEFINE_GUID(CLSID_Picture_Dib,0x316,0,0,0xc0,0,0,0,0,0,0,0x46); 28 DEFINE_GUID(CLSID_Picture_EnhMetafile,0x319,0,0,0xc0,0,0,0,0,0,0,0x46); 29 #endif 30 31 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr) 32 33 #define DEFINE_EXPECT(func) \ 34 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE 35 36 #define SET_EXPECT(func) \ 37 expect_ ## func = TRUE 38 39 #define CHECK_EXPECT2(func) \ 40 do { \ 41 ok(expect_ ##func, "unexpected call " #func "\n"); \ 42 called_ ## func = TRUE; \ 43 }while(0) 44 45 #define CHECK_EXPECT(func) \ 46 do { \ 47 CHECK_EXPECT2(func); \ 48 expect_ ## func = FALSE; \ 49 }while(0) 50 51 #define CHECK_CALLED(func) \ 52 do { \ 53 ok(called_ ## func, "expected " #func "\n"); \ 54 expect_ ## func = called_ ## func = FALSE; \ 55 }while(0) 56 57 DEFINE_EXPECT(Storage_Stat); 58 DEFINE_EXPECT(Storage_OpenStream_CompObj); 59 DEFINE_EXPECT(Storage_SetClass); 60 DEFINE_EXPECT(Storage_CreateStream_CompObj); 61 DEFINE_EXPECT(Storage_OpenStream_Ole); 62 63 static IPersistStorage OleObjectPersistStg; 64 static IOleCache *cache; 65 static IRunnableObject *runnable; 66 67 static const CLSID CLSID_WineTestOld = 68 { /* 9474ba1a-258b-490b-bc13-516e9239acd0 */ 69 0x9474ba1a, 70 0x258b, 71 0x490b, 72 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xd0} 73 }; 74 75 static const CLSID CLSID_WineTest = 76 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */ 77 0x9474ba1a, 78 0x258b, 79 0x490b, 80 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0} 81 }; 82 83 static const IID IID_WineTest = 84 { /* 9474ba1a-258b-490b-bc13-516e9239ace1 */ 85 0x9474ba1a, 86 0x258b, 87 0x490b, 88 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe1} 89 }; 90 91 #define TEST_OPTIONAL 0x1 92 #define TEST_TODO 0x2 93 94 struct expected_method 95 { 96 const char *method; 97 unsigned int flags; 98 }; 99 100 static const struct expected_method *expected_method_list; 101 static FORMATETC *g_expected_fetc = NULL; 102 103 static BOOL g_showRunnable = TRUE; 104 static BOOL g_isRunning = TRUE; 105 static HRESULT g_GetMiscStatusFailsWith = S_OK; 106 static HRESULT g_QIFailsWith; 107 108 static UINT cf_test_1, cf_test_2, cf_test_3; 109 110 /**************************************************************************** 111 * PresentationDataHeader 112 * 113 * This structure represents the header of the \002OlePresXXX stream in 114 * the OLE object storage. 115 */ 116 typedef struct PresentationDataHeader 117 { 118 /* clipformat: 119 * - standard clipformat: 120 * DWORD length = 0xffffffff; 121 * DWORD cfFormat; 122 * - or custom clipformat: 123 * DWORD length; 124 * CHAR format_name[length]; (null-terminated) 125 */ 126 DWORD unknown3; /* 4, possibly TYMED_ISTREAM */ 127 DVASPECT dvAspect; 128 DWORD lindex; 129 DWORD advf; 130 DWORD unknown7; /* 0 */ 131 DWORD dwObjectExtentX; 132 DWORD dwObjectExtentY; 133 DWORD dwSize; 134 } PresentationDataHeader; 135 136 #define CHECK_EXPECTED_METHOD(method_name) \ 137 do { \ 138 trace("%s\n", method_name); \ 139 ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); \ 140 if (!strcmp(expected_method_list->method, "WINE_EXTRA")) \ 141 { \ 142 todo_wine ok(0, "Too many method calls.\n"); \ 143 break; \ 144 } \ 145 if (expected_method_list->method) \ 146 { \ 147 while (expected_method_list->flags & TEST_OPTIONAL && \ 148 strcmp(expected_method_list->method, method_name) != 0) \ 149 expected_method_list++; \ 150 todo_wine_if (expected_method_list->flags & TEST_TODO) \ 151 ok(!strcmp(expected_method_list->method, method_name), \ 152 "Expected %s to be called instead of %s\n", \ 153 expected_method_list->method, method_name); \ 154 expected_method_list++; \ 155 } \ 156 } while(0) 157 158 #define CHECK_NO_EXTRA_METHODS() \ 159 do { \ 160 while (expected_method_list->flags & TEST_OPTIONAL) \ 161 expected_method_list++; \ 162 ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \ 163 } while (0) 164 165 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv) 166 { 167 CHECK_EXPECTED_METHOD("OleObject_QueryInterface"); 168 169 *ppv = NULL; 170 171 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleObject)) 172 *ppv = iface; 173 else if (IsEqualIID(riid, &IID_IPersistStorage)) 174 *ppv = &OleObjectPersistStg; 175 else if (IsEqualIID(riid, &IID_IOleCache)) 176 *ppv = cache; 177 else if (IsEqualIID(riid, &IID_IRunnableObject) && g_showRunnable) 178 *ppv = runnable; 179 else if (IsEqualIID(riid, &IID_WineTest)) 180 return g_QIFailsWith; 181 182 if(*ppv) { 183 IUnknown_AddRef((IUnknown*)*ppv); 184 return S_OK; 185 } 186 187 trace("OleObject_QueryInterface: returning E_NOINTERFACE\n"); 188 return E_NOINTERFACE; 189 } 190 191 static ULONG WINAPI OleObject_AddRef(IOleObject *iface) 192 { 193 CHECK_EXPECTED_METHOD("OleObject_AddRef"); 194 return 2; 195 } 196 197 static ULONG WINAPI OleObject_Release(IOleObject *iface) 198 { 199 CHECK_EXPECTED_METHOD("OleObject_Release"); 200 return 1; 201 } 202 203 static HRESULT WINAPI OleObject_SetClientSite 204 ( 205 IOleObject *iface, 206 IOleClientSite *pClientSite 207 ) 208 { 209 CHECK_EXPECTED_METHOD("OleObject_SetClientSite"); 210 return S_OK; 211 } 212 213 static HRESULT WINAPI OleObject_GetClientSite 214 ( 215 IOleObject *iface, 216 IOleClientSite **ppClientSite 217 ) 218 { 219 CHECK_EXPECTED_METHOD("OleObject_GetClientSite"); 220 return E_NOTIMPL; 221 } 222 223 static HRESULT WINAPI OleObject_SetHostNames 224 ( 225 IOleObject *iface, 226 LPCOLESTR szContainerApp, 227 LPCOLESTR szContainerObj 228 ) 229 { 230 CHECK_EXPECTED_METHOD("OleObject_SetHostNames"); 231 return S_OK; 232 } 233 234 static HRESULT WINAPI OleObject_Close 235 ( 236 IOleObject *iface, 237 DWORD dwSaveOption 238 ) 239 { 240 CHECK_EXPECTED_METHOD("OleObject_Close"); 241 return S_OK; 242 } 243 244 static HRESULT WINAPI OleObject_SetMoniker 245 ( 246 IOleObject *iface, 247 DWORD dwWhichMoniker, 248 IMoniker *pmk 249 ) 250 { 251 CHECK_EXPECTED_METHOD("OleObject_SetMoniker"); 252 return S_OK; 253 } 254 255 static HRESULT WINAPI OleObject_GetMoniker 256 ( 257 IOleObject *iface, 258 DWORD dwAssign, 259 DWORD dwWhichMoniker, 260 IMoniker **ppmk 261 ) 262 { 263 CHECK_EXPECTED_METHOD("OleObject_GetMoniker"); 264 return S_OK; 265 } 266 267 static HRESULT WINAPI OleObject_InitFromData 268 ( 269 IOleObject *iface, 270 IDataObject *pDataObject, 271 BOOL fCreation, 272 DWORD dwReserved 273 ) 274 { 275 CHECK_EXPECTED_METHOD("OleObject_InitFromData"); 276 return S_OK; 277 } 278 279 static HRESULT WINAPI OleObject_GetClipboardData 280 ( 281 IOleObject *iface, 282 DWORD dwReserved, 283 IDataObject **ppDataObject 284 ) 285 { 286 CHECK_EXPECTED_METHOD("OleObject_GetClipboardData"); 287 return E_NOTIMPL; 288 } 289 290 static HRESULT WINAPI OleObject_DoVerb 291 ( 292 IOleObject *iface, 293 LONG iVerb, 294 LPMSG lpmsg, 295 IOleClientSite *pActiveSite, 296 LONG lindex, 297 HWND hwndParent, 298 LPCRECT lprcPosRect 299 ) 300 { 301 CHECK_EXPECTED_METHOD("OleObject_DoVerb"); 302 return S_OK; 303 } 304 305 static HRESULT WINAPI OleObject_EnumVerbs 306 ( 307 IOleObject *iface, 308 IEnumOLEVERB **ppEnumOleVerb 309 ) 310 { 311 CHECK_EXPECTED_METHOD("OleObject_EnumVerbs"); 312 return E_NOTIMPL; 313 } 314 315 static HRESULT WINAPI OleObject_Update 316 ( 317 IOleObject *iface 318 ) 319 { 320 CHECK_EXPECTED_METHOD("OleObject_Update"); 321 return S_OK; 322 } 323 324 static HRESULT WINAPI OleObject_IsUpToDate 325 ( 326 IOleObject *iface 327 ) 328 { 329 CHECK_EXPECTED_METHOD("OleObject_IsUpToDate"); 330 return S_OK; 331 } 332 333 static HRESULT WINAPI OleObject_GetUserClassID 334 ( 335 IOleObject *iface, 336 CLSID *pClsid 337 ) 338 { 339 CHECK_EXPECTED_METHOD("OleObject_GetUserClassID"); 340 return E_NOTIMPL; 341 } 342 343 static HRESULT WINAPI OleObject_GetUserType 344 ( 345 IOleObject *iface, 346 DWORD dwFormOfType, 347 LPOLESTR *pszUserType 348 ) 349 { 350 CHECK_EXPECTED_METHOD("OleObject_GetUserType"); 351 return E_NOTIMPL; 352 } 353 354 static HRESULT WINAPI OleObject_SetExtent 355 ( 356 IOleObject *iface, 357 DWORD dwDrawAspect, 358 SIZEL *psizel 359 ) 360 { 361 CHECK_EXPECTED_METHOD("OleObject_SetExtent"); 362 return S_OK; 363 } 364 365 static HRESULT WINAPI OleObject_GetExtent 366 ( 367 IOleObject *iface, 368 DWORD dwDrawAspect, 369 SIZEL *psizel 370 ) 371 { 372 CHECK_EXPECTED_METHOD("OleObject_GetExtent"); 373 return E_NOTIMPL; 374 } 375 376 static HRESULT WINAPI OleObject_Advise 377 ( 378 IOleObject *iface, 379 IAdviseSink *pAdvSink, 380 DWORD *pdwConnection 381 ) 382 { 383 CHECK_EXPECTED_METHOD("OleObject_Advise"); 384 return S_OK; 385 } 386 387 static HRESULT WINAPI OleObject_Unadvise 388 ( 389 IOleObject *iface, 390 DWORD dwConnection 391 ) 392 { 393 CHECK_EXPECTED_METHOD("OleObject_Unadvise"); 394 return S_OK; 395 } 396 397 static HRESULT WINAPI OleObject_EnumAdvise 398 ( 399 IOleObject *iface, 400 IEnumSTATDATA **ppenumAdvise 401 ) 402 { 403 CHECK_EXPECTED_METHOD("OleObject_EnumAdvise"); 404 return E_NOTIMPL; 405 } 406 407 static HRESULT WINAPI OleObject_GetMiscStatus 408 ( 409 IOleObject *iface, 410 DWORD aspect, 411 DWORD *pdwStatus 412 ) 413 { 414 CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus"); 415 416 ok(aspect == DVASPECT_CONTENT, "got aspect %d\n", aspect); 417 418 if (g_GetMiscStatusFailsWith == S_OK) 419 { 420 *pdwStatus = OLEMISC_RECOMPOSEONRESIZE; 421 return S_OK; 422 } 423 else 424 { 425 *pdwStatus = 0x1234; 426 return g_GetMiscStatusFailsWith; 427 } 428 } 429 430 static HRESULT WINAPI OleObject_SetColorScheme 431 ( 432 IOleObject *iface, 433 LOGPALETTE *pLogpal 434 ) 435 { 436 CHECK_EXPECTED_METHOD("OleObject_SetColorScheme"); 437 return E_NOTIMPL; 438 } 439 440 static const IOleObjectVtbl OleObjectVtbl = 441 { 442 OleObject_QueryInterface, 443 OleObject_AddRef, 444 OleObject_Release, 445 OleObject_SetClientSite, 446 OleObject_GetClientSite, 447 OleObject_SetHostNames, 448 OleObject_Close, 449 OleObject_SetMoniker, 450 OleObject_GetMoniker, 451 OleObject_InitFromData, 452 OleObject_GetClipboardData, 453 OleObject_DoVerb, 454 OleObject_EnumVerbs, 455 OleObject_Update, 456 OleObject_IsUpToDate, 457 OleObject_GetUserClassID, 458 OleObject_GetUserType, 459 OleObject_SetExtent, 460 OleObject_GetExtent, 461 OleObject_Advise, 462 OleObject_Unadvise, 463 OleObject_EnumAdvise, 464 OleObject_GetMiscStatus, 465 OleObject_SetColorScheme 466 }; 467 468 static IOleObject OleObject = { &OleObjectVtbl }; 469 470 static HRESULT WINAPI OleObjectPersistStg_QueryInterface(IPersistStorage *iface, REFIID riid, void **ppv) 471 { 472 trace("OleObjectPersistStg_QueryInterface\n"); 473 return IOleObject_QueryInterface(&OleObject, riid, ppv); 474 } 475 476 static ULONG WINAPI OleObjectPersistStg_AddRef(IPersistStorage *iface) 477 { 478 CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef"); 479 return 2; 480 } 481 482 static ULONG WINAPI OleObjectPersistStg_Release(IPersistStorage *iface) 483 { 484 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release"); 485 return 1; 486 } 487 488 static HRESULT WINAPI OleObjectPersistStg_GetClassId(IPersistStorage *iface, CLSID *clsid) 489 { 490 CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId"); 491 return E_NOTIMPL; 492 } 493 494 static HRESULT WINAPI OleObjectPersistStg_IsDirty 495 ( 496 IPersistStorage *iface 497 ) 498 { 499 CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty"); 500 return S_OK; 501 } 502 503 static HRESULT WINAPI OleObjectPersistStg_InitNew 504 ( 505 IPersistStorage *iface, 506 IStorage *pStg 507 ) 508 { 509 CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew"); 510 return S_OK; 511 } 512 513 static HRESULT WINAPI OleObjectPersistStg_Load 514 ( 515 IPersistStorage *iface, 516 IStorage *pStg 517 ) 518 { 519 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load"); 520 return S_OK; 521 } 522 523 static HRESULT WINAPI OleObjectPersistStg_Save 524 ( 525 IPersistStorage *iface, 526 IStorage *pStgSave, 527 BOOL fSameAsLoad 528 ) 529 { 530 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save"); 531 return S_OK; 532 } 533 534 static HRESULT WINAPI OleObjectPersistStg_SaveCompleted 535 ( 536 IPersistStorage *iface, 537 IStorage *pStgNew 538 ) 539 { 540 CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted"); 541 return S_OK; 542 } 543 544 static HRESULT WINAPI OleObjectPersistStg_HandsOffStorage 545 ( 546 IPersistStorage *iface 547 ) 548 { 549 CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage"); 550 return S_OK; 551 } 552 553 static const IPersistStorageVtbl OleObjectPersistStgVtbl = 554 { 555 OleObjectPersistStg_QueryInterface, 556 OleObjectPersistStg_AddRef, 557 OleObjectPersistStg_Release, 558 OleObjectPersistStg_GetClassId, 559 OleObjectPersistStg_IsDirty, 560 OleObjectPersistStg_InitNew, 561 OleObjectPersistStg_Load, 562 OleObjectPersistStg_Save, 563 OleObjectPersistStg_SaveCompleted, 564 OleObjectPersistStg_HandsOffStorage 565 }; 566 567 static IPersistStorage OleObjectPersistStg = { &OleObjectPersistStgVtbl }; 568 569 static HRESULT WINAPI OleObjectCache_QueryInterface(IOleCache *iface, REFIID riid, void **ppv) 570 { 571 return IOleObject_QueryInterface(&OleObject, riid, ppv); 572 } 573 574 static ULONG WINAPI OleObjectCache_AddRef(IOleCache *iface) 575 { 576 CHECK_EXPECTED_METHOD("OleObjectCache_AddRef"); 577 return 2; 578 } 579 580 static ULONG WINAPI OleObjectCache_Release(IOleCache *iface) 581 { 582 CHECK_EXPECTED_METHOD("OleObjectCache_Release"); 583 return 1; 584 } 585 586 static HRESULT WINAPI OleObjectCache_Cache 587 ( 588 IOleCache *iface, 589 FORMATETC *pformatetc, 590 DWORD advf, 591 DWORD *pdwConnection 592 ) 593 { 594 CHECK_EXPECTED_METHOD("OleObjectCache_Cache"); 595 if (g_expected_fetc) { 596 ok(pformatetc != NULL, "pformatetc should not be NULL\n"); 597 if (pformatetc) { 598 ok(pformatetc->cfFormat == g_expected_fetc->cfFormat, 599 "cfFormat: %x\n", pformatetc->cfFormat); 600 ok((pformatetc->ptd != NULL) == (g_expected_fetc->ptd != NULL), 601 "ptd: %p\n", pformatetc->ptd); 602 ok(pformatetc->dwAspect == g_expected_fetc->dwAspect, 603 "dwAspect: %x\n", pformatetc->dwAspect); 604 ok(pformatetc->lindex == g_expected_fetc->lindex, 605 "lindex: %x\n", pformatetc->lindex); 606 ok(pformatetc->tymed == g_expected_fetc->tymed, 607 "tymed: %x\n", pformatetc->tymed); 608 } 609 } else 610 ok(pformatetc == NULL, "pformatetc should be NULL\n"); 611 return S_OK; 612 } 613 614 static HRESULT WINAPI OleObjectCache_Uncache 615 ( 616 IOleCache *iface, 617 DWORD dwConnection 618 ) 619 { 620 CHECK_EXPECTED_METHOD("OleObjectCache_Uncache"); 621 return S_OK; 622 } 623 624 static HRESULT WINAPI OleObjectCache_EnumCache 625 ( 626 IOleCache *iface, 627 IEnumSTATDATA **ppenumSTATDATA 628 ) 629 { 630 CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache"); 631 return S_OK; 632 } 633 634 635 static HRESULT WINAPI OleObjectCache_InitCache 636 ( 637 IOleCache *iface, 638 IDataObject *pDataObject 639 ) 640 { 641 CHECK_EXPECTED_METHOD("OleObjectCache_InitCache"); 642 return S_OK; 643 } 644 645 646 static HRESULT WINAPI OleObjectCache_SetData 647 ( 648 IOleCache *iface, 649 FORMATETC *pformatetc, 650 STGMEDIUM *pmedium, 651 BOOL fRelease 652 ) 653 { 654 CHECK_EXPECTED_METHOD("OleObjectCache_SetData"); 655 return S_OK; 656 } 657 658 659 static const IOleCacheVtbl OleObjectCacheVtbl = 660 { 661 OleObjectCache_QueryInterface, 662 OleObjectCache_AddRef, 663 OleObjectCache_Release, 664 OleObjectCache_Cache, 665 OleObjectCache_Uncache, 666 OleObjectCache_EnumCache, 667 OleObjectCache_InitCache, 668 OleObjectCache_SetData 669 }; 670 671 static IOleCache OleObjectCache = { &OleObjectCacheVtbl }; 672 673 static HRESULT WINAPI OleObjectCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) 674 { 675 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) 676 { 677 *ppv = iface; 678 IClassFactory_AddRef(iface); 679 return S_OK; 680 } 681 *ppv = NULL; 682 return E_NOINTERFACE; 683 } 684 685 static ULONG WINAPI OleObjectCF_AddRef(IClassFactory *iface) 686 { 687 return 2; 688 } 689 690 static ULONG WINAPI OleObjectCF_Release(IClassFactory *iface) 691 { 692 return 1; 693 } 694 695 static HRESULT WINAPI OleObjectCF_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID riid, void **ppv) 696 { 697 return IOleObject_QueryInterface(&OleObject, riid, ppv); 698 } 699 700 static HRESULT WINAPI OleObjectCF_LockServer(IClassFactory *iface, BOOL lock) 701 { 702 return S_OK; 703 } 704 705 static const IClassFactoryVtbl OleObjectCFVtbl = 706 { 707 OleObjectCF_QueryInterface, 708 OleObjectCF_AddRef, 709 OleObjectCF_Release, 710 OleObjectCF_CreateInstance, 711 OleObjectCF_LockServer 712 }; 713 714 static IClassFactory OleObjectCF = { &OleObjectCFVtbl }; 715 716 static HRESULT WINAPI OleObjectRunnable_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv) 717 { 718 return IOleObject_QueryInterface(&OleObject, riid, ppv); 719 } 720 721 static ULONG WINAPI OleObjectRunnable_AddRef(IRunnableObject *iface) 722 { 723 CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef"); 724 return 2; 725 } 726 727 static ULONG WINAPI OleObjectRunnable_Release(IRunnableObject *iface) 728 { 729 CHECK_EXPECTED_METHOD("OleObjectRunnable_Release"); 730 return 1; 731 } 732 733 static HRESULT WINAPI OleObjectRunnable_GetRunningClass( 734 IRunnableObject *iface, 735 LPCLSID lpClsid) 736 { 737 CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass"); 738 return E_NOTIMPL; 739 } 740 741 static HRESULT WINAPI OleObjectRunnable_Run( 742 IRunnableObject *iface, 743 LPBINDCTX pbc) 744 { 745 CHECK_EXPECTED_METHOD("OleObjectRunnable_Run"); 746 return S_OK; 747 } 748 749 static BOOL WINAPI OleObjectRunnable_IsRunning(IRunnableObject *iface) 750 { 751 CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning"); 752 return g_isRunning; 753 } 754 755 static HRESULT WINAPI OleObjectRunnable_LockRunning( 756 IRunnableObject *iface, 757 BOOL fLock, 758 BOOL fLastUnlockCloses) 759 { 760 CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning"); 761 return S_OK; 762 } 763 764 static HRESULT WINAPI OleObjectRunnable_SetContainedObject( 765 IRunnableObject *iface, 766 BOOL fContained) 767 { 768 CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject"); 769 return S_OK; 770 } 771 772 static const IRunnableObjectVtbl OleObjectRunnableVtbl = 773 { 774 OleObjectRunnable_QueryInterface, 775 OleObjectRunnable_AddRef, 776 OleObjectRunnable_Release, 777 OleObjectRunnable_GetRunningClass, 778 OleObjectRunnable_Run, 779 OleObjectRunnable_IsRunning, 780 OleObjectRunnable_LockRunning, 781 OleObjectRunnable_SetContainedObject 782 }; 783 784 static IRunnableObject OleObjectRunnable = { &OleObjectRunnableVtbl }; 785 786 static const CLSID CLSID_Equation3 = {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} }; 787 788 static HRESULT WINAPI viewobject_QueryInterface(IViewObject *iface, REFIID riid, void **obj) 789 { 790 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IViewObject)) 791 { 792 *obj = iface; 793 return S_OK; 794 } 795 796 *obj = NULL; 797 return E_NOINTERFACE; 798 } 799 800 static ULONG WINAPI viewobject_AddRef(IViewObject *iface) 801 { 802 return 2; 803 } 804 805 static ULONG WINAPI viewobject_Release(IViewObject *iface) 806 { 807 return 1; 808 } 809 810 static HRESULT WINAPI viewobject_Draw(IViewObject *iface, DWORD aspect, LONG index, 811 void *paspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, 812 LPCRECTL bounds, LPCRECTL wbounds, BOOL (STDMETHODCALLTYPE *pfnContinue)(ULONG_PTR dwContinue), 813 ULONG_PTR dwContinue) 814 { 815 ok(index == -1, "index=%d\n", index); 816 return S_OK; 817 } 818 819 static HRESULT WINAPI viewobject_GetColorSet(IViewObject *iface, DWORD draw_aspect, LONG index, 820 void *aspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **colorset) 821 { 822 ok(0, "unexpected call GetColorSet\n"); 823 return E_NOTIMPL; 824 } 825 826 static HRESULT WINAPI viewobject_Freeze(IViewObject *iface, DWORD draw_aspect, LONG index, 827 void *aspect, DWORD *freeze) 828 { 829 ok(0, "unexpected call Freeze\n"); 830 return E_NOTIMPL; 831 } 832 833 static HRESULT WINAPI viewobject_Unfreeze(IViewObject *iface, DWORD freeze) 834 { 835 ok(0, "unexpected call Unfreeze\n"); 836 return E_NOTIMPL; 837 } 838 839 static HRESULT WINAPI viewobject_SetAdvise(IViewObject *iface, DWORD aspects, DWORD advf, IAdviseSink *sink) 840 { 841 ok(0, "unexpected call SetAdvise\n"); 842 return E_NOTIMPL; 843 } 844 845 static HRESULT WINAPI viewobject_GetAdvise(IViewObject *iface, DWORD *aspects, DWORD *advf, 846 IAdviseSink **sink) 847 { 848 ok(0, "unexpected call GetAdvise\n"); 849 return E_NOTIMPL; 850 } 851 852 static const struct IViewObjectVtbl viewobjectvtbl = { 853 viewobject_QueryInterface, 854 viewobject_AddRef, 855 viewobject_Release, 856 viewobject_Draw, 857 viewobject_GetColorSet, 858 viewobject_Freeze, 859 viewobject_Unfreeze, 860 viewobject_SetAdvise, 861 viewobject_GetAdvise 862 }; 863 864 static IViewObject viewobject = { &viewobjectvtbl }; 865 866 static void test_OleCreate(IStorage *pStorage) 867 { 868 HRESULT hr; 869 IOleObject *pObject; 870 FORMATETC formatetc; 871 static const struct expected_method methods_olerender_none[] = 872 { 873 { "OleObject_QueryInterface", 0 }, 874 { "OleObject_AddRef", 0 }, 875 { "OleObject_QueryInterface", 0 }, 876 { "OleObject_AddRef", TEST_OPTIONAL }, 877 { "OleObject_Release", TEST_OPTIONAL }, 878 { "OleObject_QueryInterface", TEST_OPTIONAL }, 879 { "OleObjectPersistStg_AddRef", 0 }, 880 { "OleObjectPersistStg_InitNew", 0 }, 881 { "OleObjectPersistStg_Release", 0 }, 882 { "OleObject_Release", 0 }, 883 { "OleObject_Release", TEST_OPTIONAL }, 884 { NULL, 0 } 885 }; 886 static const struct expected_method methods_olerender_draw[] = 887 { 888 { "OleObject_QueryInterface", 0 }, 889 { "OleObject_AddRef", 0 }, 890 { "OleObject_QueryInterface", 0 }, 891 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ }, 892 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 893 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ }, 894 { "OleObjectPersistStg_AddRef", 0 }, 895 { "OleObjectPersistStg_InitNew", 0 }, 896 { "OleObjectPersistStg_Release", 0 }, 897 { "OleObject_QueryInterface", 0 }, 898 { "OleObjectRunnable_AddRef", 0 }, 899 { "OleObjectRunnable_Run", 0 }, 900 { "OleObjectRunnable_Release", 0 }, 901 { "OleObject_QueryInterface", 0 }, 902 { "OleObjectCache_AddRef", 0 }, 903 { "OleObjectCache_Cache", 0 }, 904 { "OleObjectCache_Release", 0 }, 905 { "OleObject_Release", 0 }, 906 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 907 { NULL, 0 } 908 }; 909 static const struct expected_method methods_olerender_draw_with_site[] = 910 { 911 { "OleObject_QueryInterface", 0 }, 912 { "OleObject_AddRef", 0 }, 913 { "OleObject_QueryInterface", 0 }, 914 { "OleObject_AddRef", 0 }, 915 { "OleObject_GetMiscStatus", 0 }, 916 { "OleObject_QueryInterface", 0 }, 917 { "OleObjectPersistStg_AddRef", 0 }, 918 { "OleObjectPersistStg_InitNew", 0 }, 919 { "OleObjectPersistStg_Release", 0 }, 920 { "OleObject_SetClientSite", 0 }, 921 { "OleObject_Release", 0 }, 922 { "OleObject_QueryInterface", 0 }, 923 { "OleObjectRunnable_AddRef", 0 }, 924 { "OleObjectRunnable_Run", 0 }, 925 { "OleObjectRunnable_Release", 0 }, 926 { "OleObject_QueryInterface", 0 }, 927 { "OleObjectCache_AddRef", 0 }, 928 { "OleObjectCache_Cache", 0 }, 929 { "OleObjectCache_Release", 0 }, 930 { "OleObject_Release", 0 }, 931 { NULL, 0 } 932 }; 933 static const struct expected_method methods_olerender_format[] = 934 { 935 { "OleObject_QueryInterface", 0 }, 936 { "OleObject_AddRef", 0 }, 937 { "OleObject_QueryInterface", 0 }, 938 { "OleObject_AddRef", 0 }, 939 { "OleObject_GetMiscStatus", 0 }, 940 { "OleObject_QueryInterface", 0 }, 941 { "OleObjectPersistStg_AddRef", 0 }, 942 { "OleObjectPersistStg_InitNew", 0 }, 943 { "OleObjectPersistStg_Release", 0 }, 944 { "OleObject_SetClientSite", 0 }, 945 { "OleObject_Release", 0 }, 946 { "OleObject_QueryInterface", 0 }, 947 { "OleObjectRunnable_AddRef", 0 }, 948 { "OleObjectRunnable_Run", 0 }, 949 { "OleObjectRunnable_Release", 0 }, 950 { "OleObject_QueryInterface", 0 }, 951 { "OleObjectCache_AddRef", 0 }, 952 { "OleObjectCache_Cache", 0 }, 953 { "OleObjectCache_Release", 0 }, 954 { "OleObject_Release", 0 }, 955 { NULL, 0 } 956 }; 957 static const struct expected_method methods_olerender_asis[] = 958 { 959 { "OleObject_QueryInterface", 0 }, 960 { "OleObject_AddRef", 0 }, 961 { "OleObject_QueryInterface", 0 }, 962 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ }, 963 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 964 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ }, 965 { "OleObjectPersistStg_AddRef", 0 }, 966 { "OleObjectPersistStg_InitNew", 0 }, 967 { "OleObjectPersistStg_Release", 0 }, 968 { "OleObject_Release", 0 }, 969 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 970 { NULL, 0 } 971 }; 972 static const struct expected_method methods_olerender_draw_no_runnable[] = 973 { 974 { "OleObject_QueryInterface", 0 }, 975 { "OleObject_AddRef", 0 }, 976 { "OleObject_QueryInterface", 0 }, 977 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ }, 978 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 979 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ }, 980 { "OleObjectPersistStg_AddRef", 0 }, 981 { "OleObjectPersistStg_InitNew", 0 }, 982 { "OleObjectPersistStg_Release", 0 }, 983 { "OleObject_QueryInterface", 0 }, 984 { "OleObject_QueryInterface", 0 }, 985 { "OleObjectCache_AddRef", 0 }, 986 { "OleObjectCache_Cache", 0 }, 987 { "OleObjectCache_Release", 0 }, 988 { "OleObject_Release", 0 }, 989 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 990 { NULL, 0 }, 991 }; 992 static const struct expected_method methods_olerender_draw_no_cache[] = 993 { 994 { "OleObject_QueryInterface", 0 }, 995 { "OleObject_AddRef", 0 }, 996 { "OleObject_QueryInterface", 0 }, 997 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ }, 998 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 999 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ }, 1000 { "OleObjectPersistStg_AddRef", 0 }, 1001 { "OleObjectPersistStg_InitNew", 0 }, 1002 { "OleObjectPersistStg_Release", 0 }, 1003 { "OleObject_QueryInterface", 0 }, 1004 { "OleObjectRunnable_AddRef", 0 }, 1005 { "OleObjectRunnable_Run", 0 }, 1006 { "OleObjectRunnable_Release", 0 }, 1007 { "OleObject_QueryInterface", 0 }, 1008 { "OleObject_Release", 0 }, 1009 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 1010 { NULL, 0 } 1011 }; 1012 1013 g_expected_fetc = &formatetc; 1014 formatetc.cfFormat = 0; 1015 formatetc.ptd = NULL; 1016 formatetc.dwAspect = DVASPECT_CONTENT; 1017 formatetc.lindex = -1; 1018 formatetc.tymed = TYMED_NULL; 1019 runnable = &OleObjectRunnable; 1020 cache = &OleObjectCache; 1021 expected_method_list = methods_olerender_none; 1022 trace("OleCreate with OLERENDER_NONE:\n"); 1023 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_NONE, NULL, NULL, pStorage, (void **)&pObject); 1024 ok_ole_success(hr, "OleCreate"); 1025 IOleObject_Release(pObject); 1026 CHECK_NO_EXTRA_METHODS(); 1027 1028 expected_method_list = methods_olerender_draw; 1029 trace("OleCreate with OLERENDER_DRAW:\n"); 1030 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject); 1031 ok_ole_success(hr, "OleCreate"); 1032 IOleObject_Release(pObject); 1033 CHECK_NO_EXTRA_METHODS(); 1034 1035 expected_method_list = methods_olerender_draw_with_site; 1036 trace("OleCreate with OLERENDER_DRAW, with site:\n"); 1037 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject); 1038 ok_ole_success(hr, "OleCreate"); 1039 IOleObject_Release(pObject); 1040 CHECK_NO_EXTRA_METHODS(); 1041 1042 /* GetMiscStatus fails */ 1043 g_GetMiscStatusFailsWith = 0x8fafefaf; 1044 expected_method_list = methods_olerender_draw_with_site; 1045 trace("OleCreate with OLERENDER_DRAW, with site:\n"); 1046 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject); 1047 ok_ole_success(hr, "OleCreate"); 1048 IOleObject_Release(pObject); 1049 CHECK_NO_EXTRA_METHODS(); 1050 g_GetMiscStatusFailsWith = S_OK; 1051 1052 formatetc.cfFormat = CF_TEXT; 1053 formatetc.ptd = NULL; 1054 formatetc.dwAspect = DVASPECT_CONTENT; 1055 formatetc.lindex = -1; 1056 formatetc.tymed = TYMED_HGLOBAL; 1057 expected_method_list = methods_olerender_format; 1058 trace("OleCreate with OLERENDER_FORMAT:\n"); 1059 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_FORMAT, &formatetc, (IOleClientSite *)0xdeadbeef, pStorage, (void **)&pObject); 1060 ok(hr == S_OK || 1061 broken(hr == E_INVALIDARG), /* win2k */ 1062 "OleCreate failed with error 0x%08x\n", hr); 1063 if (pObject) 1064 { 1065 IOleObject_Release(pObject); 1066 CHECK_NO_EXTRA_METHODS(); 1067 } 1068 1069 expected_method_list = methods_olerender_asis; 1070 trace("OleCreate with OLERENDER_ASIS:\n"); 1071 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_ASIS, NULL, NULL, pStorage, (void **)&pObject); 1072 ok_ole_success(hr, "OleCreate"); 1073 IOleObject_Release(pObject); 1074 CHECK_NO_EXTRA_METHODS(); 1075 1076 formatetc.cfFormat = 0; 1077 formatetc.tymed = TYMED_NULL; 1078 runnable = NULL; 1079 expected_method_list = methods_olerender_draw_no_runnable; 1080 trace("OleCreate with OLERENDER_DRAW (no IRunnableObject):\n"); 1081 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject); 1082 ok_ole_success(hr, "OleCreate"); 1083 IOleObject_Release(pObject); 1084 CHECK_NO_EXTRA_METHODS(); 1085 1086 runnable = &OleObjectRunnable; 1087 cache = NULL; 1088 expected_method_list = methods_olerender_draw_no_cache; 1089 trace("OleCreate with OLERENDER_DRAW (no IOleCache):\n"); 1090 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject); 1091 ok_ole_success(hr, "OleCreate"); 1092 IOleObject_Release(pObject); 1093 CHECK_NO_EXTRA_METHODS(); 1094 trace("end\n"); 1095 g_expected_fetc = NULL; 1096 } 1097 1098 static void test_OleLoad(IStorage *pStorage) 1099 { 1100 HRESULT hr; 1101 IOleObject *pObject; 1102 DWORD fmt; 1103 1104 static const struct expected_method methods_oleload[] = 1105 { 1106 { "OleObject_QueryInterface", 0 }, 1107 { "OleObject_AddRef", 0 }, 1108 { "OleObject_QueryInterface", 0 }, 1109 { "OleObject_AddRef", 0 }, 1110 { "OleObject_GetMiscStatus", 0 }, 1111 { "OleObject_QueryInterface", 0 }, 1112 { "OleObjectPersistStg_AddRef", 0 }, 1113 { "OleObjectPersistStg_Load", 0 }, 1114 { "OleObjectPersistStg_Release", 0 }, 1115 { "OleObject_SetClientSite", 0 }, 1116 { "OleObject_Release", 0 }, 1117 { "OleObject_QueryInterface", 0 }, 1118 { "OleObject_GetMiscStatus", 0 }, 1119 { "OleObject_Release", 0 }, 1120 { NULL, 0 } 1121 }; 1122 1123 /* Test once with IOleObject_GetMiscStatus failing */ 1124 expected_method_list = methods_oleload; 1125 g_GetMiscStatusFailsWith = E_FAIL; 1126 trace("OleLoad:\n"); 1127 hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject); 1128 ok(hr == S_OK || 1129 broken(hr == E_INVALIDARG), /* win98 and win2k */ 1130 "OleLoad failed with error 0x%08x\n", hr); 1131 if(pObject) 1132 { 1133 DWORD dwStatus = 0xdeadbeef; 1134 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus); 1135 ok(hr == E_FAIL, "Got 0x%08x\n", hr); 1136 ok(dwStatus == 0x1234, "Got 0x%08x\n", dwStatus); 1137 1138 IOleObject_Release(pObject); 1139 CHECK_NO_EXTRA_METHODS(); 1140 } 1141 g_GetMiscStatusFailsWith = S_OK; 1142 1143 /* Test again, let IOleObject_GetMiscStatus succeed. */ 1144 expected_method_list = methods_oleload; 1145 trace("OleLoad:\n"); 1146 hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject); 1147 ok(hr == S_OK || 1148 broken(hr == E_INVALIDARG), /* win98 and win2k */ 1149 "OleLoad failed with error 0x%08x\n", hr); 1150 if (pObject) 1151 { 1152 DWORD dwStatus = 0xdeadbeef; 1153 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus); 1154 ok(hr == S_OK, "Got 0x%08x\n", hr); 1155 ok(dwStatus == 1, "Got 0x%08x\n", dwStatus); 1156 1157 IOleObject_Release(pObject); 1158 CHECK_NO_EXTRA_METHODS(); 1159 } 1160 1161 for (fmt = CF_TEXT; fmt < CF_MAX; fmt++) 1162 { 1163 static const WCHAR olrepres[] = { 2,'O','l','e','P','r','e','s','0','0','0',0 }; 1164 IStorage *stg; 1165 IStream *stream; 1166 IUnknown *obj; 1167 DWORD data, i, data_size; 1168 PresentationDataHeader header; 1169 HDC hdc; 1170 HGDIOBJ hobj; 1171 RECT rc; 1172 char buf[256]; 1173 1174 for (i = 0; i < 7; i++) 1175 { 1176 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &stg); 1177 ok(hr == S_OK, "StgCreateDocfile error %#x\n", hr); 1178 1179 hr = IStorage_SetClass(stg, &CLSID_WineTest); 1180 ok(hr == S_OK, "SetClass error %#x\n", hr); 1181 1182 hr = IStorage_CreateStream(stg, olrepres, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stream); 1183 ok(hr == S_OK, "CreateStream error %#x\n", hr); 1184 1185 data = ~0; 1186 hr = IStream_Write(stream, &data, sizeof(data), NULL); 1187 ok(hr == S_OK, "Write error %#x\n", hr); 1188 1189 data = fmt; 1190 hr = IStream_Write(stream, &data, sizeof(data), NULL); 1191 ok(hr == S_OK, "Write error %#x\n", hr); 1192 1193 switch (fmt) 1194 { 1195 case CF_BITMAP: 1196 /* FIXME: figure out stream format */ 1197 hobj = CreateBitmap(1, 1, 1, 1, NULL); 1198 data_size = GetBitmapBits(hobj, sizeof(buf), buf); 1199 DeleteObject(hobj); 1200 break; 1201 1202 case CF_METAFILEPICT: 1203 case CF_ENHMETAFILE: 1204 hdc = CreateMetaFileA(NULL); 1205 hobj = CloseMetaFile(hdc); 1206 data_size = GetMetaFileBitsEx(hobj, sizeof(buf), buf); 1207 DeleteMetaFile(hobj); 1208 break; 1209 1210 default: 1211 data_size = sizeof(buf); 1212 memset(buf, 'A', sizeof(buf)); 1213 break; 1214 } 1215 1216 header.unknown3 = 4; 1217 header.dvAspect = DVASPECT_CONTENT; 1218 header.lindex = -1; 1219 header.advf = 1 << i; 1220 header.unknown7 = 0; 1221 header.dwObjectExtentX = 1; 1222 header.dwObjectExtentY = 1; 1223 header.dwSize = data_size; 1224 hr = IStream_Write(stream, &header, sizeof(header), NULL); 1225 ok(hr == S_OK, "Write error %#x\n", hr); 1226 1227 hr = IStream_Write(stream, buf, data_size, NULL); 1228 ok(hr == S_OK, "Write error %#x\n", hr); 1229 1230 IStream_Release(stream); 1231 1232 hr = OleLoad(stg, &IID_IUnknown, NULL, (void **)&obj); 1233 /* FIXME: figure out stream format */ 1234 if (fmt == CF_BITMAP && hr != S_OK) 1235 { 1236 IStorage_Release(stg); 1237 continue; 1238 } 1239 ok(hr == S_OK, "OleLoad error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf); 1240 1241 hdc = CreateCompatibleDC(0); 1242 SetRect(&rc, 0, 0, 100, 100); 1243 hr = OleDraw(obj, DVASPECT_CONTENT, hdc, &rc); 1244 DeleteDC(hdc); 1245 if (fmt == CF_METAFILEPICT) 1246 ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf); 1247 else if (fmt == CF_ENHMETAFILE) 1248 todo_wine 1249 ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf); 1250 else 1251 ok(hr == OLE_E_BLANK || hr == OLE_E_NOTRUNNING || hr == E_FAIL, "OleDraw should fail: %#x, cfFormat = %u, advf = %#x\n", hr, fmt, header.advf); 1252 1253 IUnknown_Release(obj); 1254 IStorage_Release(stg); 1255 } 1256 } 1257 } 1258 1259 static BOOL STDMETHODCALLTYPE draw_continue(ULONG_PTR param) 1260 { 1261 CHECK_EXPECTED_METHOD("draw_continue"); 1262 return TRUE; 1263 } 1264 1265 static BOOL STDMETHODCALLTYPE draw_continue_false(ULONG_PTR param) 1266 { 1267 CHECK_EXPECTED_METHOD("draw_continue_false"); 1268 return FALSE; 1269 } 1270 1271 static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface, REFIID riid, void **ppv) 1272 { 1273 if (IsEqualIID(riid, &IID_IAdviseSink) || IsEqualIID(riid, &IID_IUnknown)) 1274 { 1275 *ppv = iface; 1276 IAdviseSink_AddRef(iface); 1277 return S_OK; 1278 } 1279 *ppv = NULL; 1280 return E_NOINTERFACE; 1281 } 1282 1283 static ULONG WINAPI AdviseSink_AddRef(IAdviseSink *iface) 1284 { 1285 return 2; 1286 } 1287 1288 static ULONG WINAPI AdviseSink_Release(IAdviseSink *iface) 1289 { 1290 return 1; 1291 } 1292 1293 1294 static void WINAPI AdviseSink_OnDataChange( 1295 IAdviseSink *iface, 1296 FORMATETC *pFormatetc, 1297 STGMEDIUM *pStgmed) 1298 { 1299 CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange"); 1300 } 1301 1302 static void WINAPI AdviseSink_OnViewChange( 1303 IAdviseSink *iface, 1304 DWORD dwAspect, 1305 LONG lindex) 1306 { 1307 CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange"); 1308 } 1309 1310 static void WINAPI AdviseSink_OnRename( 1311 IAdviseSink *iface, 1312 IMoniker *pmk) 1313 { 1314 CHECK_EXPECTED_METHOD("AdviseSink_OnRename"); 1315 } 1316 1317 static void WINAPI AdviseSink_OnSave(IAdviseSink *iface) 1318 { 1319 CHECK_EXPECTED_METHOD("AdviseSink_OnSave"); 1320 } 1321 1322 static void WINAPI AdviseSink_OnClose(IAdviseSink *iface) 1323 { 1324 CHECK_EXPECTED_METHOD("AdviseSink_OnClose"); 1325 } 1326 1327 static const IAdviseSinkVtbl AdviseSinkVtbl = 1328 { 1329 AdviseSink_QueryInterface, 1330 AdviseSink_AddRef, 1331 AdviseSink_Release, 1332 AdviseSink_OnDataChange, 1333 AdviseSink_OnViewChange, 1334 AdviseSink_OnRename, 1335 AdviseSink_OnSave, 1336 AdviseSink_OnClose 1337 }; 1338 1339 static IAdviseSink AdviseSink = { &AdviseSinkVtbl }; 1340 1341 static HRESULT WINAPI DataObject_QueryInterface( 1342 IDataObject* iface, 1343 REFIID riid, 1344 void** ppvObject) 1345 { 1346 CHECK_EXPECTED_METHOD("DataObject_QueryInterface"); 1347 1348 if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown)) 1349 { 1350 *ppvObject = iface; 1351 return S_OK; 1352 } 1353 *ppvObject = NULL; 1354 return S_OK; 1355 } 1356 1357 static ULONG WINAPI DataObject_AddRef( 1358 IDataObject* iface) 1359 { 1360 CHECK_EXPECTED_METHOD("DataObject_AddRef"); 1361 return 2; 1362 } 1363 1364 static ULONG WINAPI DataObject_Release( 1365 IDataObject* iface) 1366 { 1367 CHECK_EXPECTED_METHOD("DataObject_Release"); 1368 return 1; 1369 } 1370 1371 static HRESULT WINAPI DataObject_GetData( 1372 IDataObject* iface, 1373 LPFORMATETC pformatetcIn, 1374 STGMEDIUM* pmedium) 1375 { 1376 CHECK_EXPECTED_METHOD("DataObject_GetData"); 1377 return E_NOTIMPL; 1378 } 1379 1380 static HRESULT WINAPI DataObject_GetDataHere( 1381 IDataObject* iface, 1382 LPFORMATETC pformatetc, 1383 STGMEDIUM* pmedium) 1384 { 1385 CHECK_EXPECTED_METHOD("DataObject_GetDataHere"); 1386 return E_NOTIMPL; 1387 } 1388 1389 static HRESULT WINAPI DataObject_QueryGetData( 1390 IDataObject* iface, 1391 LPFORMATETC pformatetc) 1392 { 1393 CHECK_EXPECTED_METHOD("DataObject_QueryGetData"); 1394 return S_OK; 1395 } 1396 1397 static HRESULT WINAPI DataObject_GetCanonicalFormatEtc( 1398 IDataObject* iface, 1399 LPFORMATETC pformatectIn, 1400 LPFORMATETC pformatetcOut) 1401 { 1402 CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc"); 1403 return E_NOTIMPL; 1404 } 1405 1406 static HRESULT WINAPI DataObject_SetData( 1407 IDataObject* iface, 1408 LPFORMATETC pformatetc, 1409 STGMEDIUM* pmedium, 1410 BOOL fRelease) 1411 { 1412 CHECK_EXPECTED_METHOD("DataObject_SetData"); 1413 return E_NOTIMPL; 1414 } 1415 1416 static HRESULT WINAPI DataObject_EnumFormatEtc( 1417 IDataObject* iface, 1418 DWORD dwDirection, 1419 IEnumFORMATETC** ppenumFormatEtc) 1420 { 1421 CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc"); 1422 return E_NOTIMPL; 1423 } 1424 1425 static HRESULT WINAPI DataObject_DAdvise( 1426 IDataObject* iface, 1427 FORMATETC* pformatetc, 1428 DWORD advf, 1429 IAdviseSink* pAdvSink, 1430 DWORD* pdwConnection) 1431 { 1432 STGMEDIUM stgmedium; 1433 1434 CHECK_EXPECTED_METHOD("DataObject_DAdvise"); 1435 *pdwConnection = 1; 1436 1437 if(advf & ADVF_PRIMEFIRST) 1438 { 1439 ok(pformatetc->cfFormat == cf_test_2, "got %04x\n", pformatetc->cfFormat); 1440 stgmedium.tymed = TYMED_HGLOBAL; 1441 U(stgmedium).hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 4); 1442 stgmedium.pUnkForRelease = NULL; 1443 IAdviseSink_OnDataChange(pAdvSink, pformatetc, &stgmedium); 1444 } 1445 1446 return S_OK; 1447 } 1448 1449 static HRESULT WINAPI DataObject_DUnadvise( 1450 IDataObject* iface, 1451 DWORD dwConnection) 1452 { 1453 CHECK_EXPECTED_METHOD("DataObject_DUnadvise"); 1454 return S_OK; 1455 } 1456 1457 static HRESULT WINAPI DataObject_EnumDAdvise( 1458 IDataObject* iface, 1459 IEnumSTATDATA** ppenumAdvise) 1460 { 1461 CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise"); 1462 return OLE_E_ADVISENOTSUPPORTED; 1463 } 1464 1465 static IDataObjectVtbl DataObjectVtbl = 1466 { 1467 DataObject_QueryInterface, 1468 DataObject_AddRef, 1469 DataObject_Release, 1470 DataObject_GetData, 1471 DataObject_GetDataHere, 1472 DataObject_QueryGetData, 1473 DataObject_GetCanonicalFormatEtc, 1474 DataObject_SetData, 1475 DataObject_EnumFormatEtc, 1476 DataObject_DAdvise, 1477 DataObject_DUnadvise, 1478 DataObject_EnumDAdvise 1479 }; 1480 1481 static IDataObject DataObject = { &DataObjectVtbl }; 1482 1483 static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) 1484 { 1485 *ppv = NULL; 1486 if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface; 1487 if (*ppv) 1488 { 1489 IUnknown_AddRef((IUnknown *)*ppv); 1490 return S_OK; 1491 } 1492 return E_NOINTERFACE; 1493 } 1494 1495 static ULONG WINAPI Unknown_AddRef(IUnknown *iface) 1496 { 1497 return 2; 1498 } 1499 1500 static ULONG WINAPI Unknown_Release(IUnknown *iface) 1501 { 1502 return 1; 1503 } 1504 1505 static const IUnknownVtbl UnknownVtbl = 1506 { 1507 Unknown_QueryInterface, 1508 Unknown_AddRef, 1509 Unknown_Release 1510 }; 1511 1512 static IUnknown unknown = { &UnknownVtbl }; 1513 1514 static void check_enum_cache(IOleCache2 *cache, const STATDATA *expect, int num) 1515 { 1516 IEnumSTATDATA *enum_stat; 1517 STATDATA stat; 1518 HRESULT hr; 1519 1520 hr = IOleCache2_EnumCache( cache, &enum_stat ); 1521 ok( hr == S_OK, "got %08x\n", hr ); 1522 1523 while (IEnumSTATDATA_Next(enum_stat, 1, &stat, NULL) == S_OK) 1524 { 1525 ok( stat.formatetc.cfFormat == expect->formatetc.cfFormat, "got %d expect %d\n", 1526 stat.formatetc.cfFormat, expect->formatetc.cfFormat ); 1527 ok( !stat.formatetc.ptd == !expect->formatetc.ptd, "got %p expect %p\n", 1528 stat.formatetc.ptd, expect->formatetc.ptd ); 1529 ok( stat.formatetc.dwAspect == expect->formatetc.dwAspect, "got %d expect %d\n", 1530 stat.formatetc.dwAspect, expect->formatetc.dwAspect ); 1531 ok( stat.formatetc.lindex == expect->formatetc.lindex, "got %d expect %d\n", 1532 stat.formatetc.lindex, expect->formatetc.lindex ); 1533 ok( stat.formatetc.tymed == expect->formatetc.tymed, "got %d expect %d\n", 1534 stat.formatetc.tymed, expect->formatetc.tymed ); 1535 ok( stat.advf == expect->advf, "got %d expect %d\n", stat.advf, expect->advf ); 1536 ok( stat.pAdvSink == 0, "got %p\n", stat.pAdvSink ); 1537 ok( stat.dwConnection == expect->dwConnection, "got %d expect %d\n", stat.dwConnection, expect->dwConnection ); 1538 num--; 1539 expect++; 1540 } 1541 1542 ok( num == 0, "incorrect number. num %d\n", num ); 1543 1544 IEnumSTATDATA_Release( enum_stat ); 1545 } 1546 1547 static void test_data_cache(void) 1548 { 1549 HRESULT hr; 1550 IOleCache2 *pOleCache; 1551 IOleCache *olecache; 1552 IStorage *pStorage; 1553 IUnknown *unk; 1554 IPersistStorage *pPS; 1555 IViewObject *pViewObject; 1556 IOleCacheControl *pOleCacheControl; 1557 IDataObject *pCacheDataObject; 1558 FORMATETC fmtetc; 1559 STGMEDIUM stgmedium; 1560 DWORD dwConnection; 1561 DWORD dwFreeze; 1562 RECTL rcBounds; 1563 HDC hdcMem; 1564 CLSID clsid; 1565 char szSystemDir[MAX_PATH]; 1566 WCHAR wszPath[MAX_PATH]; 1567 static const WCHAR wszShell32[] = {'\\','s','h','e','l','l','3','2','.','d','l','l',0}; 1568 1569 static const struct expected_method methods_cacheinitnew[] = 1570 { 1571 { "AdviseSink_OnViewChange", 0 }, 1572 { "AdviseSink_OnViewChange", 0 }, 1573 { "draw_continue", 1 }, 1574 { "draw_continue_false", 1 }, 1575 { "DataObject_DAdvise", 0 }, 1576 { "DataObject_DAdvise", 0 }, 1577 { "DataObject_DUnadvise", 0 }, 1578 { "DataObject_DUnadvise", 0 }, 1579 { NULL, 0 } 1580 }; 1581 static const struct expected_method methods_cacheload[] = 1582 { 1583 { "AdviseSink_OnViewChange", 0 }, 1584 { "draw_continue", 1 }, 1585 { "draw_continue", 1 }, 1586 { "draw_continue", 1 }, 1587 { "DataObject_GetData", 0 }, 1588 { "DataObject_GetData", 0 }, 1589 { "DataObject_GetData", 0 }, 1590 { NULL, 0 } 1591 }; 1592 static const struct expected_method methods_cachethenrun[] = 1593 { 1594 { "DataObject_DAdvise", 0 }, 1595 { "DataObject_DAdvise", 0 }, 1596 { "DataObject_DAdvise", 0 }, 1597 { "DataObject_QueryGetData", 1 }, /* called by win9x and nt4 */ 1598 { "DataObject_DAdvise", 0 }, 1599 { "DataObject_DUnadvise", 0 }, 1600 { "DataObject_DUnadvise", 0 }, 1601 { "DataObject_DUnadvise", 0 }, 1602 { "DataObject_DUnadvise", 0 }, 1603 { NULL, 0 } 1604 }; 1605 1606 GetSystemDirectoryA(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0])); 1607 1608 expected_method_list = methods_cacheinitnew; 1609 1610 fmtetc.cfFormat = CF_METAFILEPICT; 1611 fmtetc.dwAspect = DVASPECT_ICON; 1612 fmtetc.lindex = -1; 1613 fmtetc.ptd = NULL; 1614 fmtetc.tymed = TYMED_MFPICT; 1615 1616 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage); 1617 ok_ole_success(hr, "StgCreateDocfile"); 1618 1619 /* aggregation */ 1620 1621 /* requested is not IUnknown */ 1622 hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IOleCache2, (void**)&pOleCache); 1623 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 1624 1625 hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IUnknown, (void**)&unk); 1626 ok(hr == S_OK, "got 0x%08x\n", hr); 1627 1628 hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache); 1629 ok(hr == S_OK, "got 0x%08x\n", hr); 1630 hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache); 1631 ok(hr == S_OK, "got 0x%08x\n", hr); 1632 ok(unk != (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk); 1633 ok(unk != (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk); 1634 IOleCache2_Release(pOleCache); 1635 IOleCache_Release(olecache); 1636 IUnknown_Release(unk); 1637 1638 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IUnknown, (void**)&unk); 1639 ok(hr == S_OK, "got 0x%08x\n", hr); 1640 hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache); 1641 ok(hr == S_OK, "got 0x%08x\n", hr); 1642 hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache); 1643 ok(hr == S_OK, "got 0x%08x\n", hr); 1644 todo_wine { 1645 ok(unk == (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk); 1646 ok(unk == (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk); 1647 } 1648 IOleCache2_Release(pOleCache); 1649 IOleCache_Release(olecache); 1650 IUnknown_Release(unk); 1651 1652 /* Test with new data */ 1653 1654 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache); 1655 ok_ole_success(hr, "CreateDataCache"); 1656 1657 hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS); 1658 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)"); 1659 hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject); 1660 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)"); 1661 hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl); 1662 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)"); 1663 1664 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink); 1665 ok_ole_success(hr, "IViewObject_SetAdvise"); 1666 1667 hr = IPersistStorage_InitNew(pPS, pStorage); 1668 ok_ole_success(hr, "IPersistStorage_InitNew"); 1669 1670 hr = IPersistStorage_IsDirty(pPS); 1671 ok_ole_success(hr, "IPersistStorage_IsDirty"); 1672 1673 hr = IPersistStorage_GetClassID(pPS, &clsid); 1674 ok_ole_success(hr, "IPersistStorage_GetClassID"); 1675 ok(IsEqualCLSID(&clsid, &IID_NULL), "clsid should be blank\n"); 1676 1677 hr = IOleCache2_Uncache(pOleCache, 0xdeadbeef); 1678 ok(hr == OLE_E_NOCONNECTION, "IOleCache_Uncache with invalid value should return OLE_E_NOCONNECTION instead of 0x%x\n", hr); 1679 1680 /* Both tests crash on NT4 and below. StgCreatePropSetStg is only available on w2k and above. */ 1681 if (GetProcAddress(GetModuleHandleA("ole32.dll"), "StgCreatePropSetStg")) 1682 { 1683 hr = IOleCache2_Cache(pOleCache, NULL, 0, &dwConnection); 1684 ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL fmtetc should have returned E_INVALIDARG instead of 0x%08x\n", hr); 1685 1686 hr = IOleCache2_Cache(pOleCache, NULL, 0, NULL); 1687 ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL pdwConnection should have returned E_INVALIDARG instead of 0x%08x\n", hr); 1688 } 1689 else 1690 { 1691 skip("tests with NULL parameters will crash on NT4 and below\n"); 1692 } 1693 1694 for (fmtetc.cfFormat = CF_TEXT; fmtetc.cfFormat < CF_MAX; fmtetc.cfFormat++) 1695 { 1696 int i; 1697 fmtetc.dwAspect = DVASPECT_THUMBNAIL; 1698 for (i = 0; i < 7; i++) 1699 { 1700 fmtetc.tymed = 1 << i; 1701 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 1702 if ((fmtetc.cfFormat == CF_METAFILEPICT && fmtetc.tymed == TYMED_MFPICT) || 1703 (fmtetc.cfFormat == CF_BITMAP && fmtetc.tymed == TYMED_GDI) || 1704 (fmtetc.cfFormat == CF_DIB && fmtetc.tymed == TYMED_HGLOBAL) || 1705 (fmtetc.cfFormat == CF_ENHMETAFILE && fmtetc.tymed == TYMED_ENHMF)) 1706 ok(hr == S_OK, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned S_OK instead of 0x%08x\n", 1707 fmtetc.cfFormat, fmtetc.tymed, hr); 1708 else if (fmtetc.tymed == TYMED_HGLOBAL) 1709 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED || 1710 broken(hr == S_OK && fmtetc.cfFormat == CF_BITMAP) /* Win9x & NT4 */, 1711 "IOleCache_Cache cfFormat = %d, tymed = %d should have returned CACHE_S_FORMATETC_NOTSUPPORTED instead of 0x%08x\n", 1712 fmtetc.cfFormat, fmtetc.tymed, hr); 1713 else 1714 ok(hr == DV_E_TYMED, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned DV_E_TYMED instead of 0x%08x\n", 1715 fmtetc.cfFormat, fmtetc.tymed, hr); 1716 if (SUCCEEDED(hr)) 1717 { 1718 hr = IOleCache2_Uncache(pOleCache, dwConnection); 1719 ok_ole_success(hr, "IOleCache_Uncache"); 1720 } 1721 } 1722 } 1723 1724 fmtetc.cfFormat = CF_BITMAP; 1725 fmtetc.dwAspect = DVASPECT_THUMBNAIL; 1726 fmtetc.tymed = TYMED_GDI; 1727 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 1728 ok_ole_success(hr, "IOleCache_Cache"); 1729 1730 fmtetc.cfFormat = 0; 1731 fmtetc.dwAspect = DVASPECT_ICON; 1732 fmtetc.tymed = TYMED_MFPICT; 1733 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 1734 ok_ole_success(hr, "IOleCache_Cache"); 1735 1736 MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, sizeof(wszPath)/sizeof(wszPath[0])); 1737 memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32)); 1738 1739 fmtetc.cfFormat = CF_METAFILEPICT; 1740 stgmedium.tymed = TYMED_MFPICT; 1741 U(stgmedium).hMetaFilePict = OleMetafilePictFromIconAndLabel( 1742 LoadIconA(NULL, (LPSTR)IDI_APPLICATION), wszPath, wszPath, 0); 1743 stgmedium.pUnkForRelease = NULL; 1744 1745 fmtetc.dwAspect = DVASPECT_CONTENT; 1746 hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE); 1747 ok(hr == OLE_E_BLANK, "IOleCache_SetData for aspect not in cache should have return OLE_E_BLANK instead of 0x%08x\n", hr); 1748 1749 fmtetc.dwAspect = DVASPECT_ICON; 1750 hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE); 1751 ok_ole_success(hr, "IOleCache_SetData"); 1752 ReleaseStgMedium(&stgmedium); 1753 1754 hr = IViewObject_Freeze(pViewObject, DVASPECT_ICON, -1, NULL, &dwFreeze); 1755 todo_wine { 1756 ok_ole_success(hr, "IViewObject_Freeze"); 1757 hr = IViewObject_Freeze(pViewObject, DVASPECT_CONTENT, -1, NULL, &dwFreeze); 1758 ok(hr == OLE_E_BLANK, "IViewObject_Freeze with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr); 1759 } 1760 1761 rcBounds.left = 0; 1762 rcBounds.top = 0; 1763 rcBounds.right = 100; 1764 rcBounds.bottom = 100; 1765 hdcMem = CreateCompatibleDC(NULL); 1766 1767 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 1768 ok_ole_success(hr, "IViewObject_Draw"); 1769 1770 hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 1771 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr); 1772 1773 /* a NULL draw_continue fn ptr */ 1774 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, NULL, 0xdeadbeef); 1775 ok_ole_success(hr, "IViewObject_Draw"); 1776 1777 /* draw_continue that returns FALSE to abort drawing */ 1778 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue_false, 0xdeadbeef); 1779 ok(hr == E_ABORT || 1780 broken(hr == S_OK), /* win9x may skip the callbacks */ 1781 "IViewObject_Draw with draw_continue_false returns 0x%08x\n", hr); 1782 1783 DeleteDC(hdcMem); 1784 1785 hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject); 1786 ok_ole_success(hr, "IOleCacheControl_OnRun"); 1787 1788 hr = IPersistStorage_Save(pPS, pStorage, TRUE); 1789 ok_ole_success(hr, "IPersistStorage_Save"); 1790 1791 hr = IPersistStorage_SaveCompleted(pPS, NULL); 1792 ok_ole_success(hr, "IPersistStorage_SaveCompleted"); 1793 1794 hr = IPersistStorage_IsDirty(pPS); 1795 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr); 1796 1797 IPersistStorage_Release(pPS); 1798 IViewObject_Release(pViewObject); 1799 IOleCache2_Release(pOleCache); 1800 IOleCacheControl_Release(pOleCacheControl); 1801 1802 CHECK_NO_EXTRA_METHODS(); 1803 1804 /* Test with loaded data */ 1805 trace("Testing loaded data with CreateDataCache:\n"); 1806 expected_method_list = methods_cacheload; 1807 1808 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache); 1809 ok_ole_success(hr, "CreateDataCache"); 1810 1811 hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS); 1812 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)"); 1813 hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject); 1814 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)"); 1815 1816 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink); 1817 ok_ole_success(hr, "IViewObject_SetAdvise"); 1818 1819 hr = IPersistStorage_Load(pPS, pStorage); 1820 ok_ole_success(hr, "IPersistStorage_Load"); 1821 1822 hr = IPersistStorage_IsDirty(pPS); 1823 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr); 1824 1825 fmtetc.cfFormat = 0; 1826 fmtetc.dwAspect = DVASPECT_ICON; 1827 fmtetc.lindex = -1; 1828 fmtetc.ptd = NULL; 1829 fmtetc.tymed = TYMED_MFPICT; 1830 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 1831 ok(hr == CACHE_S_SAMECACHE, "IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x\n", hr); 1832 1833 rcBounds.left = 0; 1834 rcBounds.top = 0; 1835 rcBounds.right = 100; 1836 rcBounds.bottom = 100; 1837 hdcMem = CreateCompatibleDC(NULL); 1838 1839 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 1840 ok_ole_success(hr, "IViewObject_Draw"); 1841 1842 hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 1843 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr); 1844 1845 /* unload the cached storage object, causing it to be reloaded */ 1846 hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE); 1847 ok_ole_success(hr, "IOleCache2_DiscardCache"); 1848 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 1849 ok_ole_success(hr, "IViewObject_Draw"); 1850 1851 /* unload the cached storage object, but don't allow it to be reloaded */ 1852 hr = IPersistStorage_HandsOffStorage(pPS); 1853 ok_ole_success(hr, "IPersistStorage_HandsOffStorage"); 1854 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 1855 ok_ole_success(hr, "IViewObject_Draw"); 1856 hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE); 1857 ok_ole_success(hr, "IOleCache2_DiscardCache"); 1858 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 1859 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr); 1860 1861 DeleteDC(hdcMem); 1862 1863 todo_wine { 1864 hr = IOleCache2_InitCache(pOleCache, &DataObject); 1865 ok(hr == CACHE_E_NOCACHE_UPDATED, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr); 1866 } 1867 1868 IPersistStorage_Release(pPS); 1869 IViewObject_Release(pViewObject); 1870 IOleCache2_Release(pOleCache); 1871 1872 todo_wine { 1873 CHECK_NO_EXTRA_METHODS(); 1874 } 1875 1876 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache); 1877 ok_ole_success(hr, "CreateDataCache"); 1878 1879 expected_method_list = methods_cachethenrun; 1880 1881 hr = IOleCache2_QueryInterface(pOleCache, &IID_IDataObject, (LPVOID *)&pCacheDataObject); 1882 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IDataObject)"); 1883 hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl); 1884 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)"); 1885 1886 fmtetc.cfFormat = CF_METAFILEPICT; 1887 fmtetc.dwAspect = DVASPECT_CONTENT; 1888 fmtetc.tymed = TYMED_MFPICT; 1889 1890 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 1891 ok_ole_success(hr, "IOleCache_Cache"); 1892 1893 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); 1894 ok(hr == OLE_E_BLANK, "got %08x\n", hr); 1895 1896 fmtetc.cfFormat = cf_test_1; 1897 fmtetc.dwAspect = DVASPECT_CONTENT; 1898 fmtetc.tymed = TYMED_HGLOBAL; 1899 1900 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 1901 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr); 1902 1903 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); 1904 ok(hr == OLE_E_BLANK, "got %08x\n", hr); 1905 1906 fmtetc.cfFormat = cf_test_2; 1907 hr = IOleCache2_Cache(pOleCache, &fmtetc, ADVF_PRIMEFIRST, &dwConnection); 1908 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr); 1909 1910 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); 1911 ok(hr == OLE_E_BLANK, "got %08x\n", hr); 1912 1913 hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject); 1914 ok_ole_success(hr, "IOleCacheControl_OnRun"); 1915 1916 fmtetc.cfFormat = cf_test_3; 1917 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 1918 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr); 1919 1920 fmtetc.cfFormat = cf_test_1; 1921 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); 1922 ok(hr == OLE_E_BLANK, "got %08x\n", hr); 1923 1924 fmtetc.cfFormat = cf_test_2; 1925 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); 1926 ok(hr == S_OK, "got %08x\n", hr); 1927 ReleaseStgMedium(&stgmedium); 1928 1929 fmtetc.cfFormat = cf_test_3; 1930 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); 1931 ok(hr == OLE_E_BLANK, "got %08x\n", hr); 1932 1933 IOleCacheControl_Release(pOleCacheControl); 1934 IDataObject_Release(pCacheDataObject); 1935 IOleCache2_Release(pOleCache); 1936 1937 CHECK_NO_EXTRA_METHODS(); 1938 1939 IStorage_Release(pStorage); 1940 } 1941 1942 1943 static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0}; 1944 1945 /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */ 1946 static BYTE dib[] = 1947 { 1948 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 1949 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, 1950 1951 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 1952 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 1953 1954 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 1955 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 1956 1957 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 1958 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 1959 }; 1960 1961 static IStorage *create_storage( int num ) 1962 { 1963 IStorage *stg; 1964 IStream *stm; 1965 HRESULT hr; 1966 ULONG written; 1967 1968 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg ); 1969 ok( hr == S_OK, "got %08x\n", hr); 1970 hr = IStorage_SetClass( stg, &CLSID_Picture_Dib ); 1971 ok( hr == S_OK, "got %08x\n", hr); 1972 hr = IStorage_CreateStream( stg, CONTENTS, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stm ); 1973 ok( hr == S_OK, "got %08x\n", hr); 1974 if (num == 1) /* Set biXPelsPerMeter = 0 */ 1975 { 1976 dib[0x26] = 0; 1977 dib[0x27] = 0; 1978 } 1979 hr = IStream_Write( stm, dib, sizeof(dib), &written ); 1980 ok( hr == S_OK, "got %08x\n", hr); 1981 IStream_Release( stm ); 1982 return stg; 1983 } 1984 1985 static HGLOBAL create_dib( void ) 1986 { 1987 HGLOBAL h; 1988 void *ptr; 1989 1990 h = GlobalAlloc( GMEM_MOVEABLE, sizeof(dib) - sizeof(BITMAPFILEHEADER) ); 1991 ptr = GlobalLock( h ); 1992 memcpy( ptr, dib + sizeof(BITMAPFILEHEADER), sizeof(dib) - sizeof(BITMAPFILEHEADER) ); 1993 GlobalUnlock( h ); 1994 return h; 1995 } 1996 1997 static void test_data_cache_dib_contents_stream(int num) 1998 { 1999 HRESULT hr; 2000 IUnknown *unk; 2001 IPersistStorage *persist; 2002 IDataObject *data; 2003 IViewObject2 *view; 2004 IStorage *stg; 2005 IOleCache2 *cache; 2006 FORMATETC fmt = {CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; 2007 STGMEDIUM med; 2008 CLSID cls; 2009 SIZEL sz; 2010 BYTE *ptr; 2011 BITMAPINFOHEADER expect_info; 2012 STATDATA enum_expect[] = 2013 { 2014 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 }, 2015 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 }, 2016 }; 2017 2018 hr = CreateDataCache( NULL, &CLSID_Picture_Metafile, &IID_IUnknown, (void **)&unk ); 2019 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2020 hr = IUnknown_QueryInterface( unk, &IID_IPersistStorage, (void **)&persist ); 2021 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2022 hr = IUnknown_QueryInterface( unk, &IID_IDataObject, (void **)&data ); 2023 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2024 hr = IUnknown_QueryInterface( unk, &IID_IViewObject2, (void **)&view ); 2025 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2026 hr = IUnknown_QueryInterface( unk, &IID_IOleCache2, (void **)&cache ); 2027 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2028 2029 stg = create_storage( num ); 2030 2031 hr = IPersistStorage_Load( persist, stg ); 2032 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2033 IStorage_Release( stg ); 2034 2035 hr = IPersistStorage_GetClassID( persist, &cls ); 2036 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2037 ok( IsEqualCLSID( &cls, &CLSID_Picture_Dib ), "class id mismatch\n" ); 2038 2039 hr = IDataObject_GetData( data, &fmt, &med ); 2040 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2041 ok( med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed ); 2042 ok( GlobalSize( U(med).hGlobal ) >= sizeof(dib) - sizeof(BITMAPFILEHEADER), 2043 "got %lu\n", GlobalSize( U(med).hGlobal ) ); 2044 ptr = GlobalLock( U(med).hGlobal ); 2045 2046 expect_info = *(BITMAPINFOHEADER *)(dib + sizeof(BITMAPFILEHEADER)); 2047 if (expect_info.biXPelsPerMeter == 0 || expect_info.biYPelsPerMeter == 0) 2048 { 2049 HDC hdc = GetDC( 0 ); 2050 expect_info.biXPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSX ), 10000, 254 ); 2051 expect_info.biYPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSY ), 10000, 254 ); 2052 ReleaseDC( 0, hdc ); 2053 } 2054 ok( !memcmp( ptr, &expect_info, sizeof(expect_info) ), "mismatch\n" ); 2055 ok( !memcmp( ptr + sizeof(expect_info), dib + sizeof(BITMAPFILEHEADER) + sizeof(expect_info), 2056 sizeof(dib) - sizeof(BITMAPFILEHEADER) - sizeof(expect_info) ), "mismatch\n" ); 2057 GlobalUnlock( U(med).hGlobal ); 2058 ReleaseStgMedium( &med ); 2059 2060 check_enum_cache( cache, enum_expect, 2 ); 2061 2062 hr = IViewObject2_GetExtent( view, DVASPECT_CONTENT, -1, NULL, &sz ); 2063 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2064 if (num == 0) 2065 { 2066 ok( sz.cx == 1000, "got %d\n", sz.cx ); 2067 ok( sz.cy == 250, "got %d\n", sz.cy ); 2068 } 2069 else 2070 { 2071 HDC hdc = GetDC( 0 ); 2072 LONG x = 2 * 2540 / GetDeviceCaps( hdc, LOGPIXELSX ); 2073 LONG y = 1 * 2540 / GetDeviceCaps( hdc, LOGPIXELSY ); 2074 ok( sz.cx == x, "got %d %d\n", sz.cx, x ); 2075 ok( sz.cy == y, "got %d %d\n", sz.cy, y ); 2076 2077 ReleaseDC( 0, hdc ); 2078 } 2079 2080 IOleCache2_Release( cache ); 2081 IViewObject2_Release( view ); 2082 IDataObject_Release( data ); 2083 IPersistStorage_Release( persist ); 2084 IUnknown_Release( unk ); 2085 } 2086 2087 static void check_bitmap_size( HBITMAP h, int cx, int cy ) 2088 { 2089 BITMAP bm; 2090 2091 GetObjectW( h, sizeof(bm), &bm ); 2092 ok( bm.bmWidth == cx, "got %d expect %d\n", bm.bmWidth, cx ); 2093 ok( bm.bmHeight == cy, "got %d expect %d\n", bm.bmHeight, cy ); 2094 } 2095 2096 static void check_dib_size( HGLOBAL h, int cx, int cy ) 2097 { 2098 BITMAPINFO *info; 2099 2100 info = GlobalLock( h ); 2101 ok( info->bmiHeader.biWidth == cx, "got %d expect %d\n", info->bmiHeader.biWidth, cx ); 2102 ok( info->bmiHeader.biHeight == cy, "got %d expect %d\n", info->bmiHeader.biHeight, cy ); 2103 GlobalUnlock( h ); 2104 } 2105 2106 static void test_data_cache_bitmap(void) 2107 { 2108 HRESULT hr; 2109 IOleCache2 *cache; 2110 IDataObject *data; 2111 FORMATETC fmt; 2112 DWORD conn; 2113 STGMEDIUM med; 2114 STATDATA expect[] = 2115 { 2116 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 }, 2117 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 0 }, 2118 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 0 }, 2119 {{ CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 0 } 2120 }; 2121 2122 hr = CreateDataCache( NULL, &CLSID_NULL, &IID_IOleCache2, (void **)&cache ); 2123 ok( hr == S_OK, "got %08x\n", hr ); 2124 2125 /* create a dib entry which will also create a bitmap entry too */ 2126 fmt.cfFormat = CF_DIB; 2127 fmt.ptd = NULL; 2128 fmt.dwAspect = DVASPECT_CONTENT; 2129 fmt.lindex = -1; 2130 fmt.tymed = TYMED_HGLOBAL; 2131 2132 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2133 ok( hr == S_OK, "got %08x\n", hr ); 2134 ok( conn == 2, "got %d\n", conn ); 2135 expect[0].dwConnection = conn; 2136 expect[1].dwConnection = conn; 2137 2138 check_enum_cache( cache, expect, 2 ); 2139 2140 /* now try to add a bitmap */ 2141 fmt.cfFormat = CF_BITMAP; 2142 fmt.tymed = TYMED_GDI; 2143 2144 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2145 ok( hr == CACHE_S_SAMECACHE, "got %08x\n", hr ); 2146 2147 /* metafile */ 2148 fmt.cfFormat = CF_METAFILEPICT; 2149 fmt.tymed = TYMED_MFPICT; 2150 2151 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2152 ok( hr == S_OK, "got %08x\n", hr ); 2153 ok( conn == 3, "got %d\n", conn ); 2154 expect[2].dwConnection = conn; 2155 2156 check_enum_cache( cache, expect, 3); 2157 2158 /* enhmetafile */ 2159 fmt.cfFormat = CF_ENHMETAFILE; 2160 fmt.tymed = TYMED_ENHMF; 2161 2162 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2163 ok( hr == S_OK, "got %08x\n", hr ); 2164 ok( conn == 4, "got %d\n", conn ); 2165 expect[3].dwConnection = conn; 2166 2167 check_enum_cache( cache, expect, 4 ); 2168 2169 /* uncache everything */ 2170 hr = IOleCache2_Uncache( cache, expect[3].dwConnection ); 2171 ok( hr == S_OK, "got %08x\n", hr ); 2172 hr = IOleCache2_Uncache( cache, expect[2].dwConnection ); 2173 ok( hr == S_OK, "got %08x\n", hr ); 2174 hr = IOleCache2_Uncache( cache, expect[0].dwConnection ); 2175 ok( hr == S_OK, "got %08x\n", hr ); 2176 hr = IOleCache2_Uncache( cache, expect[0].dwConnection ); 2177 ok( hr == OLE_E_NOCONNECTION, "got %08x\n", hr ); 2178 2179 check_enum_cache( cache, expect, 0 ); 2180 2181 /* just create a bitmap entry which again adds both dib and bitmap */ 2182 fmt.cfFormat = CF_BITMAP; 2183 fmt.tymed = TYMED_GDI; 2184 2185 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2186 ok( hr == S_OK, "got %08x\n", hr ); 2187 2188 expect[0].dwConnection = conn; 2189 expect[1].dwConnection = conn; 2190 2191 check_enum_cache( cache, expect, 2 ); 2192 2193 /* Try setting a 1x1 bitmap */ 2194 hr = IOleCache2_QueryInterface( cache, &IID_IDataObject, (void **) &data ); 2195 ok( hr == S_OK, "got %08x\n", hr ); 2196 2197 med.tymed = TYMED_GDI; 2198 U(med).hBitmap = CreateBitmap( 1, 1, 1, 1, NULL ); 2199 med.pUnkForRelease = NULL; 2200 2201 hr = IOleCache2_SetData( cache, &fmt, &med, TRUE ); 2202 ok( hr == S_OK, "got %08x\n", hr ); 2203 2204 hr = IDataObject_GetData( data, &fmt, &med ); 2205 ok( hr == S_OK, "got %08x\n", hr ); 2206 ok( med.tymed == TYMED_GDI, "got %d\n", med.tymed ); 2207 check_bitmap_size( U(med).hBitmap, 1, 1 ); 2208 ReleaseStgMedium( &med ); 2209 2210 fmt.cfFormat = CF_DIB; 2211 fmt.tymed = TYMED_HGLOBAL; 2212 hr = IDataObject_GetData( data, &fmt, &med ); 2213 ok( hr == S_OK, "got %08x\n", hr ); 2214 ok( med.tymed == TYMED_HGLOBAL, "got %d\n", med.tymed ); 2215 check_dib_size( U(med).hGlobal, 1, 1 ); 2216 ReleaseStgMedium( &med ); 2217 2218 /* Now set a 2x1 dib */ 2219 fmt.cfFormat = CF_DIB; 2220 fmt.tymed = TYMED_HGLOBAL; 2221 med.tymed = TYMED_HGLOBAL; 2222 U(med).hGlobal = create_dib(); 2223 2224 hr = IOleCache2_SetData( cache, &fmt, &med, TRUE ); 2225 ok( hr == S_OK, "got %08x\n", hr ); 2226 2227 fmt.cfFormat = CF_BITMAP; 2228 fmt.tymed = TYMED_GDI; 2229 hr = IDataObject_GetData( data, &fmt, &med ); 2230 ok( hr == S_OK, "got %08x\n", hr ); 2231 ok( med.tymed == TYMED_GDI, "got %d\n", med.tymed ); 2232 check_bitmap_size( U(med).hBitmap, 2, 1 ); 2233 ReleaseStgMedium( &med ); 2234 2235 fmt.cfFormat = CF_DIB; 2236 fmt.tymed = TYMED_HGLOBAL; 2237 hr = IDataObject_GetData( data, &fmt, &med ); 2238 ok( hr == S_OK, "got %08x\n", hr ); 2239 ok( med.tymed == TYMED_HGLOBAL, "got %d\n", med.tymed ); 2240 check_dib_size( U(med).hGlobal, 2, 1 ); 2241 ReleaseStgMedium( &med ); 2242 2243 IDataObject_Release( data ); 2244 IOleCache2_Release( cache ); 2245 } 2246 2247 /* The CLSID_Picture_ classes automatically create appropriate cache entries */ 2248 static void test_data_cache_init(void) 2249 { 2250 HRESULT hr; 2251 IOleCache2 *cache; 2252 IPersistStorage *persist; 2253 int i; 2254 CLSID clsid; 2255 static const STATDATA enum_expect[] = 2256 { 2257 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 }, 2258 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 }, 2259 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 1 }, 2260 {{ CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 1 } 2261 }; 2262 static const struct 2263 { 2264 const CLSID *clsid; 2265 int enum_start, enum_num; 2266 } data[] = 2267 { 2268 { &CLSID_NULL, 0, 0 }, 2269 { &CLSID_WineTestOld, 0, 0 }, 2270 { &CLSID_Picture_Dib, 0, 2 }, 2271 { &CLSID_Picture_Metafile, 2, 1 }, 2272 { &CLSID_Picture_EnhMetafile, 3, 1 } 2273 }; 2274 2275 for (i = 0; i < sizeof(data) / sizeof(data[0]); i++) 2276 { 2277 hr = CreateDataCache( NULL, data[i].clsid, &IID_IOleCache2, (void **)&cache ); 2278 ok( hr == S_OK, "got %08x\n", hr ); 2279 2280 check_enum_cache( cache, enum_expect + data[i].enum_start , data[i].enum_num ); 2281 2282 IOleCache2_QueryInterface( cache, &IID_IPersistStorage, (void **) &persist ); 2283 hr = IPersistStorage_GetClassID( persist, &clsid ); 2284 ok( hr == S_OK, "got %08x\n", hr ); 2285 ok( IsEqualCLSID( &clsid, data[i].clsid ), "class id mismatch %s %s\n", wine_dbgstr_guid( &clsid ), 2286 wine_dbgstr_guid( data[i].clsid ) ); 2287 2288 IPersistStorage_Release( persist ); 2289 IOleCache2_Release( cache ); 2290 } 2291 } 2292 2293 static void test_data_cache_initnew(void) 2294 { 2295 HRESULT hr; 2296 IOleCache2 *cache; 2297 IPersistStorage *persist; 2298 IStorage *stg_dib, *stg_mf, *stg_wine; 2299 CLSID clsid; 2300 static const STATDATA initnew_expect[] = 2301 { 2302 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 }, 2303 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 }, 2304 }; 2305 static const STATDATA initnew2_expect[] = 2306 { 2307 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 1 }, 2308 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 }, 2309 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 }, 2310 }; 2311 static const STATDATA initnew3_expect[] = 2312 { 2313 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 }, 2314 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 }, 2315 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 }, 2316 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 }, 2317 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 3 }, 2318 }; 2319 static const STATDATA initnew4_expect[] = 2320 { 2321 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 }, 2322 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 }, 2323 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 3 }, 2324 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 4 }, 2325 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 4 }, 2326 }; 2327 2328 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_dib ); 2329 ok( hr == S_OK, "got %08x\n", hr); 2330 hr = IStorage_SetClass( stg_dib, &CLSID_Picture_Dib ); 2331 ok( hr == S_OK, "got %08x\n", hr); 2332 2333 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_mf ); 2334 ok( hr == S_OK, "got %08x\n", hr); 2335 hr = IStorage_SetClass( stg_mf, &CLSID_Picture_Metafile ); 2336 ok( hr == S_OK, "got %08x\n", hr); 2337 2338 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_wine ); 2339 ok( hr == S_OK, "got %08x\n", hr); 2340 hr = IStorage_SetClass( stg_wine, &CLSID_WineTestOld ); 2341 ok( hr == S_OK, "got %08x\n", hr); 2342 2343 hr = CreateDataCache( NULL, &CLSID_WineTestOld, &IID_IOleCache2, (void **)&cache ); 2344 ok( hr == S_OK, "got %08x\n", hr ); 2345 IOleCache2_QueryInterface( cache, &IID_IPersistStorage, (void **) &persist ); 2346 2347 hr = IPersistStorage_InitNew( persist, stg_dib ); 2348 ok( hr == S_OK, "got %08x\n", hr); 2349 2350 hr = IPersistStorage_GetClassID( persist, &clsid ); 2351 ok( hr == S_OK, "got %08x\n", hr ); 2352 ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) ); 2353 2354 check_enum_cache( cache, initnew_expect, 2 ); 2355 2356 hr = IPersistStorage_InitNew( persist, stg_mf ); 2357 ok( hr == CO_E_ALREADYINITIALIZED, "got %08x\n", hr); 2358 2359 hr = IPersistStorage_HandsOffStorage( persist ); 2360 ok( hr == S_OK, "got %08x\n", hr); 2361 2362 hr = IPersistStorage_GetClassID( persist, &clsid ); 2363 ok( hr == S_OK, "got %08x\n", hr ); 2364 ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) ); 2365 2366 hr = IPersistStorage_InitNew( persist, stg_mf ); 2367 ok( hr == S_OK, "got %08x\n", hr); 2368 2369 hr = IPersistStorage_GetClassID( persist, &clsid ); 2370 ok( hr == S_OK, "got %08x\n", hr ); 2371 ok( IsEqualCLSID( &clsid, &CLSID_Picture_Metafile ), "got %s\n", wine_dbgstr_guid( &clsid ) ); 2372 2373 check_enum_cache( cache, initnew2_expect, 3 ); 2374 2375 hr = IPersistStorage_HandsOffStorage( persist ); 2376 ok( hr == S_OK, "got %08x\n", hr); 2377 2378 hr = IPersistStorage_InitNew( persist, stg_dib ); 2379 ok( hr == S_OK, "got %08x\n", hr); 2380 2381 hr = IPersistStorage_GetClassID( persist, &clsid ); 2382 ok( hr == S_OK, "got %08x\n", hr ); 2383 ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) ); 2384 2385 check_enum_cache( cache, initnew3_expect, 5 ); 2386 2387 hr = IPersistStorage_HandsOffStorage( persist ); 2388 ok( hr == S_OK, "got %08x\n", hr); 2389 2390 hr = IPersistStorage_InitNew( persist, stg_wine ); 2391 ok( hr == S_OK, "got %08x\n", hr); 2392 2393 hr = IPersistStorage_GetClassID( persist, &clsid ); 2394 ok( hr == S_OK, "got %08x\n", hr ); 2395 ok( IsEqualCLSID( &clsid, &CLSID_WineTestOld ), "got %s\n", wine_dbgstr_guid( &clsid ) ); 2396 2397 check_enum_cache( cache, initnew4_expect, 5 ); 2398 2399 IStorage_Release( stg_wine ); 2400 IStorage_Release( stg_mf ); 2401 IStorage_Release( stg_dib ); 2402 2403 IPersistStorage_Release( persist ); 2404 IOleCache2_Release( cache ); 2405 } 2406 2407 static void test_default_handler(void) 2408 { 2409 HRESULT hr; 2410 IOleObject *pObject; 2411 IRunnableObject *pRunnableObject; 2412 IOleClientSite *pClientSite; 2413 IDataObject *pDataObject; 2414 SIZEL sizel; 2415 DWORD dwStatus; 2416 CLSID clsid; 2417 LPOLESTR pszUserType; 2418 LOGPALETTE palette; 2419 DWORD dwAdvConn; 2420 IMoniker *pMoniker; 2421 FORMATETC fmtetc; 2422 IOleInPlaceObject *pInPlaceObj; 2423 IEnumOLEVERB *pEnumVerbs; 2424 DWORD dwRegister; 2425 static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0}; 2426 static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0}; 2427 static const WCHAR wszDelim[] = {'!',0}; 2428 2429 static const struct expected_method methods_embeddinghelper[] = 2430 { 2431 { "OleObject_QueryInterface", 0 }, 2432 { "OleObject_AddRef", 0 }, 2433 { "OleObject_QueryInterface", 0 }, 2434 { "OleObject_QueryInterface", TEST_TODO }, 2435 { "OleObject_QueryInterface", 0 }, 2436 { "OleObject_QueryInterface", 0 }, 2437 { "OleObject_QueryInterface", TEST_OPTIONAL }, /* Win95/98/NT4 */ 2438 { "OleObject_Release", TEST_TODO }, 2439 { "WINE_EXTRA", TEST_OPTIONAL }, 2440 { NULL, 0 } 2441 }; 2442 2443 hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject); 2444 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); 2445 2446 hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject); 2447 ok_ole_success(hr, "OleCreateDefaultHandler"); 2448 2449 hr = IOleObject_QueryInterface(pObject, &IID_IOleInPlaceObject, (void **)&pInPlaceObj); 2450 ok(hr == E_NOINTERFACE, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr); 2451 2452 hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn); 2453 ok_ole_success(hr, "IOleObject_Advise"); 2454 2455 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE); 2456 ok_ole_success(hr, "IOleObject_Close"); 2457 2458 /* FIXME: test IOleObject_EnumAdvise */ 2459 2460 hr = IOleObject_EnumVerbs(pObject, &pEnumVerbs); 2461 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); 2462 2463 hr = IOleObject_GetClientSite(pObject, &pClientSite); 2464 ok_ole_success(hr, "IOleObject_GetClientSite"); 2465 2466 hr = IOleObject_SetClientSite(pObject, pClientSite); 2467 ok_ole_success(hr, "IOleObject_SetClientSite"); 2468 2469 hr = IOleObject_GetClipboardData(pObject, 0, &pDataObject); 2470 ok(hr == OLE_E_NOTRUNNING, 2471 "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", 2472 hr); 2473 2474 hr = IOleObject_GetExtent(pObject, DVASPECT_CONTENT, &sizel); 2475 ok(hr == OLE_E_BLANK, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n", 2476 hr); 2477 2478 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus); 2479 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); 2480 2481 hr = IOleObject_GetUserClassID(pObject, &clsid); 2482 ok_ole_success(hr, "IOleObject_GetUserClassID"); 2483 ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n"); 2484 2485 hr = IOleObject_GetUserType(pObject, USERCLASSTYPE_FULL, &pszUserType); 2486 todo_wine { 2487 ok_ole_success(hr, "IOleObject_GetUserType"); 2488 ok(!lstrcmpW(pszUserType, wszUnknown), "Retrieved user type was wrong\n"); 2489 } 2490 2491 hr = IOleObject_InitFromData(pObject, NULL, TRUE, 0); 2492 ok(hr == OLE_E_NOTRUNNING, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); 2493 2494 hr = IOleObject_IsUpToDate(pObject); 2495 ok(hr == OLE_E_NOTRUNNING, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); 2496 2497 palette.palNumEntries = 1; 2498 palette.palVersion = 2; 2499 memset(&palette.palPalEntry[0], 0, sizeof(palette.palPalEntry[0])); 2500 hr = IOleObject_SetColorScheme(pObject, &palette); 2501 ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); 2502 2503 sizel.cx = sizel.cy = 0; 2504 hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel); 2505 ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); 2506 2507 hr = IOleObject_SetHostNames(pObject, wszHostName, NULL); 2508 ok_ole_success(hr, "IOleObject_SetHostNames"); 2509 2510 hr = CreateItemMoniker(wszDelim, wszHostName, &pMoniker); 2511 ok_ole_success(hr, "CreateItemMoniker"); 2512 hr = IOleObject_SetMoniker(pObject, OLEWHICHMK_CONTAINER, pMoniker); 2513 ok_ole_success(hr, "IOleObject_SetMoniker"); 2514 IMoniker_Release(pMoniker); 2515 2516 hr = IOleObject_GetMoniker(pObject, OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &pMoniker); 2517 ok(hr == E_FAIL, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr); 2518 2519 hr = IOleObject_Update(pObject); 2520 todo_wine 2521 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); 2522 2523 hr = IOleObject_QueryInterface(pObject, &IID_IDataObject, (void **)&pDataObject); 2524 ok_ole_success(hr, "IOleObject_QueryInterface"); 2525 2526 fmtetc.cfFormat = CF_TEXT; 2527 fmtetc.ptd = NULL; 2528 fmtetc.dwAspect = DVASPECT_CONTENT; 2529 fmtetc.lindex = -1; 2530 fmtetc.tymed = TYMED_NULL; 2531 hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn); 2532 ok_ole_success(hr, "IDataObject_DAdvise"); 2533 2534 fmtetc.cfFormat = CF_ENHMETAFILE; 2535 fmtetc.ptd = NULL; 2536 fmtetc.dwAspect = DVASPECT_CONTENT; 2537 fmtetc.lindex = -1; 2538 fmtetc.tymed = TYMED_ENHMF; 2539 hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn); 2540 ok_ole_success(hr, "IDataObject_DAdvise"); 2541 2542 fmtetc.cfFormat = CF_ENHMETAFILE; 2543 fmtetc.ptd = NULL; 2544 fmtetc.dwAspect = DVASPECT_CONTENT; 2545 fmtetc.lindex = -1; 2546 fmtetc.tymed = TYMED_ENHMF; 2547 hr = IDataObject_QueryGetData(pDataObject, &fmtetc); 2548 ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); 2549 2550 fmtetc.cfFormat = CF_TEXT; 2551 fmtetc.ptd = NULL; 2552 fmtetc.dwAspect = DVASPECT_CONTENT; 2553 fmtetc.lindex = -1; 2554 fmtetc.tymed = TYMED_NULL; 2555 hr = IDataObject_QueryGetData(pDataObject, &fmtetc); 2556 ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); 2557 2558 hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnableObject); 2559 ok_ole_success(hr, "IOleObject_QueryInterface"); 2560 2561 hr = IRunnableObject_SetContainedObject(pRunnableObject, TRUE); 2562 ok_ole_success(hr, "IRunnableObject_SetContainedObject"); 2563 2564 hr = IRunnableObject_Run(pRunnableObject, NULL); 2565 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); 2566 2567 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE); 2568 ok_ole_success(hr, "IOleObject_Close"); 2569 2570 IRunnableObject_Release(pRunnableObject); 2571 IOleObject_Release(pObject); 2572 2573 /* Test failure propagation from delegate ::QueryInterface */ 2574 hr = CoRegisterClassObject(&CLSID_WineTest, (IUnknown*)&OleObjectCF, 2575 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister); 2576 ok_ole_success(hr, "CoRegisterClassObject"); 2577 if(SUCCEEDED(hr)) 2578 { 2579 expected_method_list = methods_embeddinghelper; 2580 hr = OleCreateEmbeddingHelper(&CLSID_WineTest, NULL, EMBDHLP_INPROC_SERVER, 2581 &OleObjectCF, &IID_IOleObject, (void**)&pObject); 2582 ok_ole_success(hr, "OleCreateEmbeddingHelper"); 2583 if(SUCCEEDED(hr)) 2584 { 2585 IUnknown *punk; 2586 2587 g_QIFailsWith = E_FAIL; 2588 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk); 2589 ok(hr == E_FAIL, "Got 0x%08x\n", hr); 2590 2591 g_QIFailsWith = E_NOINTERFACE; 2592 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk); 2593 ok(hr == E_NOINTERFACE, "Got 0x%08x\n", hr); 2594 2595 g_QIFailsWith = CO_E_OBJNOTCONNECTED; 2596 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk); 2597 ok(hr == CO_E_OBJNOTCONNECTED, "Got 0x%08x\n", hr); 2598 2599 g_QIFailsWith = 0x87654321; 2600 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk); 2601 ok(hr == 0x87654321, "Got 0x%08x\n", hr); 2602 2603 IOleObject_Release(pObject); 2604 } 2605 2606 CHECK_NO_EXTRA_METHODS(); 2607 2608 hr = CoRevokeClassObject(dwRegister); 2609 ok_ole_success(hr, "CoRevokeClassObject"); 2610 } 2611 } 2612 2613 static void test_runnable(void) 2614 { 2615 static const struct expected_method methods_query_runnable[] = 2616 { 2617 { "OleObject_QueryInterface", 0 }, 2618 { "OleObjectRunnable_AddRef", 0 }, 2619 { "OleObjectRunnable_IsRunning", 0 }, 2620 { "OleObjectRunnable_Release", 0 }, 2621 { NULL, 0 } 2622 }; 2623 2624 static const struct expected_method methods_no_runnable[] = 2625 { 2626 { "OleObject_QueryInterface", 0 }, 2627 { NULL, 0 } 2628 }; 2629 2630 BOOL ret; 2631 IOleObject *object = &OleObject; 2632 2633 /* null argument */ 2634 ret = OleIsRunning(NULL); 2635 ok(ret == FALSE, "got %d\n", ret); 2636 2637 expected_method_list = methods_query_runnable; 2638 ret = OleIsRunning(object); 2639 ok(ret == TRUE, "Object should be running\n"); 2640 CHECK_NO_EXTRA_METHODS(); 2641 2642 g_isRunning = FALSE; 2643 expected_method_list = methods_query_runnable; 2644 ret = OleIsRunning(object); 2645 ok(ret == FALSE, "Object should not be running\n"); 2646 CHECK_NO_EXTRA_METHODS(); 2647 2648 g_showRunnable = FALSE; /* QueryInterface(IID_IRunnableObject, ...) will fail */ 2649 expected_method_list = methods_no_runnable; 2650 ret = OleIsRunning(object); 2651 ok(ret == TRUE, "Object without IRunnableObject should be running\n"); 2652 CHECK_NO_EXTRA_METHODS(); 2653 2654 g_isRunning = TRUE; 2655 g_showRunnable = TRUE; 2656 } 2657 2658 2659 static HRESULT WINAPI OleRun_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv) 2660 { 2661 *ppv = NULL; 2662 2663 if (IsEqualIID(riid, &IID_IUnknown) || 2664 IsEqualIID(riid, &IID_IRunnableObject)) { 2665 *ppv = iface; 2666 } 2667 2668 if (*ppv) 2669 { 2670 IUnknown_AddRef((IUnknown *)*ppv); 2671 return S_OK; 2672 } 2673 2674 return E_NOINTERFACE; 2675 } 2676 2677 static ULONG WINAPI OleRun_AddRef(IRunnableObject *iface) 2678 { 2679 return 2; 2680 } 2681 2682 static ULONG WINAPI OleRun_Release(IRunnableObject *iface) 2683 { 2684 return 1; 2685 } 2686 2687 static HRESULT WINAPI OleRun_GetRunningClass(IRunnableObject *iface, CLSID *clsid) 2688 { 2689 ok(0, "unexpected\n"); 2690 return E_NOTIMPL; 2691 } 2692 2693 static HRESULT WINAPI OleRun_Run(IRunnableObject *iface, LPBINDCTX ctx) 2694 { 2695 ok(ctx == NULL, "got %p\n", ctx); 2696 return 0xdeadc0de; 2697 } 2698 2699 static BOOL WINAPI OleRun_IsRunning(IRunnableObject *iface) 2700 { 2701 ok(0, "unexpected\n"); 2702 return FALSE; 2703 } 2704 2705 static HRESULT WINAPI OleRun_LockRunning(IRunnableObject *iface, BOOL lock, 2706 BOOL last_unlock_closes) 2707 { 2708 ok(0, "unexpected\n"); 2709 return E_NOTIMPL; 2710 } 2711 2712 static HRESULT WINAPI OleRun_SetContainedObject(IRunnableObject *iface, BOOL contained) 2713 { 2714 ok(0, "unexpected\n"); 2715 return E_NOTIMPL; 2716 } 2717 2718 static const IRunnableObjectVtbl oleruntestvtbl = 2719 { 2720 OleRun_QueryInterface, 2721 OleRun_AddRef, 2722 OleRun_Release, 2723 OleRun_GetRunningClass, 2724 OleRun_Run, 2725 OleRun_IsRunning, 2726 OleRun_LockRunning, 2727 OleRun_SetContainedObject 2728 }; 2729 2730 static IRunnableObject testrunnable = { &oleruntestvtbl }; 2731 2732 static void test_OleRun(void) 2733 { 2734 HRESULT hr; 2735 2736 /* doesn't support IRunnableObject */ 2737 hr = OleRun(&unknown); 2738 ok(hr == S_OK, "OleRun failed 0x%08x\n", hr); 2739 2740 hr = OleRun((IUnknown*)&testrunnable); 2741 ok(hr == 0xdeadc0de, "got 0x%08x\n", hr); 2742 } 2743 2744 static void test_OleLockRunning(void) 2745 { 2746 HRESULT hr; 2747 2748 hr = OleLockRunning(&unknown, TRUE, FALSE); 2749 ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr); 2750 } 2751 2752 static void test_OleDraw(void) 2753 { 2754 HRESULT hr; 2755 RECT rect; 2756 2757 hr = OleDraw((IUnknown*)&viewobject, 0, (HDC)0x1, NULL); 2758 ok(hr == S_OK, "got 0x%08x\n", hr); 2759 2760 hr = OleDraw(NULL, 0, (HDC)0x1, NULL); 2761 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 2762 2763 hr = OleDraw(NULL, 0, (HDC)0x1, &rect); 2764 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 2765 } 2766 2767 static const WCHAR comp_objW[] = {1,'C','o','m','p','O','b','j',0}; 2768 static IStream *comp_obj_stream; 2769 static IStream *ole_stream; 2770 2771 static HRESULT WINAPI Storage_QueryInterface(IStorage *iface, REFIID riid, void **ppvObject) 2772 { 2773 ok(0, "unexpected call to QueryInterface\n"); 2774 return E_NOTIMPL; 2775 } 2776 2777 static ULONG WINAPI Storage_AddRef(IStorage *iface) 2778 { 2779 ok(0, "unexpected call to AddRef\n"); 2780 return 2; 2781 } 2782 2783 static ULONG WINAPI Storage_Release(IStorage *iface) 2784 { 2785 ok(0, "unexpected call to Release\n"); 2786 return 1; 2787 } 2788 2789 static HRESULT WINAPI Storage_CreateStream(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm) 2790 { 2791 ULARGE_INTEGER size = {{0}}; 2792 LARGE_INTEGER pos = {{0}}; 2793 HRESULT hr; 2794 2795 CHECK_EXPECT(Storage_CreateStream_CompObj); 2796 ok(!lstrcmpW(pwcsName, comp_objW), "pwcsName = %s\n", wine_dbgstr_w(pwcsName)); 2797 todo_wine ok(grfMode == (STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode); 2798 ok(!reserved1, "reserved1 = %x\n", reserved1); 2799 ok(!reserved2, "reserved2 = %x\n", reserved2); 2800 ok(!!ppstm, "ppstm = NULL\n"); 2801 2802 *ppstm = comp_obj_stream; 2803 IStream_AddRef(comp_obj_stream); 2804 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL); 2805 ok(hr == S_OK, "IStream_Seek returned %x\n", hr); 2806 hr = IStream_SetSize(comp_obj_stream, size); 2807 ok(hr == S_OK, "IStream_SetSize returned %x\n", hr); 2808 return S_OK; 2809 } 2810 2811 static HRESULT WINAPI Storage_OpenStream(IStorage *iface, LPCOLESTR pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm) 2812 { 2813 static const WCHAR ole1W[] = {1,'O','l','e',0}; 2814 2815 LARGE_INTEGER pos = {{0}}; 2816 HRESULT hr; 2817 2818 ok(!reserved1, "reserved1 = %p\n", reserved1); 2819 ok(!reserved2, "reserved2 = %x\n", reserved2); 2820 ok(!!ppstm, "ppstm = NULL\n"); 2821 2822 if(!lstrcmpW(pwcsName, comp_objW)) { 2823 CHECK_EXPECT2(Storage_OpenStream_CompObj); 2824 ok(grfMode == STGM_SHARE_EXCLUSIVE, "grfMode = %x\n", grfMode); 2825 2826 *ppstm = comp_obj_stream; 2827 IStream_AddRef(comp_obj_stream); 2828 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL); 2829 ok(hr == S_OK, "IStream_Seek returned %x\n", hr); 2830 return S_OK; 2831 }else if(!lstrcmpW(pwcsName, ole1W)) { 2832 CHECK_EXPECT(Storage_OpenStream_Ole); 2833 ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode); 2834 2835 *ppstm = ole_stream; 2836 IStream_AddRef(ole_stream); 2837 hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL); 2838 ok(hr == S_OK, "IStream_Seek returned %x\n", hr); 2839 return S_OK; 2840 } 2841 2842 ok(0, "unexpected call to OpenStream: %s\n", wine_dbgstr_w(pwcsName)); 2843 return E_NOTIMPL; 2844 } 2845 2846 static HRESULT WINAPI Storage_CreateStorage(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD dwStgFmt, DWORD reserved2, IStorage **ppstg) 2847 { 2848 ok(0, "unexpected call to CreateStorage\n"); 2849 return E_NOTIMPL; 2850 } 2851 2852 static HRESULT WINAPI Storage_OpenStorage(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg) 2853 { 2854 ok(0, "unexpected call to OpenStorage\n"); 2855 return E_NOTIMPL; 2856 } 2857 2858 static HRESULT WINAPI Storage_CopyTo(IStorage *iface, DWORD ciidExclude, const IID *rgiidExclude, SNB snbExclude, IStorage *pstgDest) 2859 { 2860 ok(0, "unexpected call to CopyTo\n"); 2861 return E_NOTIMPL; 2862 } 2863 2864 static HRESULT WINAPI Storage_MoveElementTo(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgDest, LPCOLESTR pwcsNewName, DWORD grfFlags) 2865 { 2866 ok(0, "unexpected call to MoveElementTo\n"); 2867 return E_NOTIMPL; 2868 } 2869 2870 static HRESULT WINAPI Storage_Commit(IStorage *iface, DWORD grfCommitFlags) 2871 { 2872 ok(0, "unexpected call to Commit\n"); 2873 return E_NOTIMPL; 2874 } 2875 2876 static HRESULT WINAPI Storage_Revert(IStorage *iface) 2877 { 2878 ok(0, "unexpected call to Revert\n"); 2879 return E_NOTIMPL; 2880 } 2881 2882 static HRESULT WINAPI Storage_EnumElements(IStorage *iface, DWORD reserved1, void *reserved2, DWORD reserved3, IEnumSTATSTG **ppenum) 2883 { 2884 ok(0, "unexpected call to EnumElements\n"); 2885 return E_NOTIMPL; 2886 } 2887 2888 static HRESULT WINAPI Storage_DestroyElement(IStorage *iface, LPCOLESTR pwcsName) 2889 { 2890 ok(0, "unexpected call to DestroyElement\n"); 2891 return E_NOTIMPL; 2892 } 2893 2894 static HRESULT WINAPI Storage_RenameElement(IStorage *iface, LPCOLESTR pwcsOldName, LPCOLESTR pwcsNewName) 2895 { 2896 ok(0, "unexpected call to RenameElement\n"); 2897 return E_NOTIMPL; 2898 } 2899 2900 static HRESULT WINAPI Storage_SetElementTimes(IStorage *iface, LPCOLESTR pwcsName, const FILETIME *pctime, const FILETIME *patime, const FILETIME *pmtime) 2901 { 2902 ok(0, "unexpected call to SetElementTimes\n"); 2903 return E_NOTIMPL; 2904 } 2905 2906 static HRESULT WINAPI Storage_SetClass(IStorage *iface, REFCLSID clsid) 2907 { 2908 CHECK_EXPECT(Storage_SetClass); 2909 ok(IsEqualIID(clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(clsid)); 2910 return S_OK; 2911 } 2912 2913 static HRESULT WINAPI Storage_SetStateBits(IStorage *iface, DWORD grfStateBits, DWORD grfMask) 2914 { 2915 ok(0, "unexpected call to SetStateBits\n"); 2916 return E_NOTIMPL; 2917 } 2918 2919 static HRESULT WINAPI Storage_Stat(IStorage *iface, STATSTG *pstatstg, DWORD grfStatFlag) 2920 { 2921 CHECK_EXPECT2(Storage_Stat); 2922 ok(pstatstg != NULL, "pstatstg = NULL\n"); 2923 ok(grfStatFlag == STATFLAG_NONAME, "grfStatFlag = %x\n", grfStatFlag); 2924 2925 memset(pstatstg, 0, sizeof(STATSTG)); 2926 pstatstg->type = STGTY_STORAGE; 2927 pstatstg->clsid = CLSID_WineTestOld; 2928 return S_OK; 2929 } 2930 2931 static IStorageVtbl StorageVtbl = 2932 { 2933 Storage_QueryInterface, 2934 Storage_AddRef, 2935 Storage_Release, 2936 Storage_CreateStream, 2937 Storage_OpenStream, 2938 Storage_CreateStorage, 2939 Storage_OpenStorage, 2940 Storage_CopyTo, 2941 Storage_MoveElementTo, 2942 Storage_Commit, 2943 Storage_Revert, 2944 Storage_EnumElements, 2945 Storage_DestroyElement, 2946 Storage_RenameElement, 2947 Storage_SetElementTimes, 2948 Storage_SetClass, 2949 Storage_SetStateBits, 2950 Storage_Stat 2951 }; 2952 2953 static IStorage Storage = { &StorageVtbl }; 2954 2955 static void test_OleDoAutoConvert(void) 2956 { 2957 static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0}; 2958 static struct { 2959 DWORD reserved1; 2960 DWORD version; 2961 DWORD reserved2[5]; 2962 DWORD ansi_user_type_len; 2963 DWORD ansi_clipboard_format_len; 2964 DWORD reserved3; 2965 DWORD unicode_marker; 2966 DWORD unicode_user_type_len; 2967 DWORD unicode_clipboard_format_len; 2968 DWORD reserved4; 2969 } comp_obj_data; 2970 static struct { 2971 DWORD version; 2972 DWORD flags; 2973 DWORD link_update_option; 2974 DWORD reserved1; 2975 DWORD reserved_moniker_stream_size; 2976 DWORD relative_source_moniker_stream_size; 2977 DWORD absolute_source_moniker_stream_size; 2978 DWORD clsid_indicator; 2979 CLSID clsid; 2980 DWORD reserved_display_name; 2981 DWORD reserved2; 2982 DWORD local_update_time; 2983 DWORD local_check_update_time; 2984 DWORD remote_update_time; 2985 } ole_data; 2986 2987 LARGE_INTEGER pos = {{0}}; 2988 WCHAR buf[39+6]; 2989 DWORD i, ret; 2990 HKEY root; 2991 CLSID clsid; 2992 HRESULT hr; 2993 2994 hr = CreateStreamOnHGlobal(NULL, TRUE, &comp_obj_stream); 2995 ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr); 2996 hr = IStream_Write(comp_obj_stream, (char*)&comp_obj_data, sizeof(comp_obj_data), NULL); 2997 ok(hr == S_OK, "IStream_Write returned %x\n", hr); 2998 2999 hr = CreateStreamOnHGlobal(NULL, TRUE, &ole_stream); 3000 ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr); 3001 hr = IStream_Write(ole_stream, (char*)&ole_data, sizeof(ole_data), NULL); 3002 ok(hr == S_OK, "IStream_Write returned %x\n", hr); 3003 3004 clsid = IID_WineTest; 3005 hr = OleDoAutoConvert(NULL, &clsid); 3006 ok(hr == E_INVALIDARG, "OleDoAutoConvert returned %x\n", hr); 3007 ok(IsEqualIID(&clsid, &IID_NULL), "clsid = %s\n", wine_dbgstr_guid(&clsid)); 3008 3009 if(0) /* crashes on Win7 */ 3010 OleDoAutoConvert(&Storage, NULL); 3011 3012 clsid = IID_WineTest; 3013 SET_EXPECT(Storage_Stat); 3014 hr = OleDoAutoConvert(&Storage, &clsid); 3015 ok(hr == REGDB_E_CLASSNOTREG, "OleDoAutoConvert returned %x\n", hr); 3016 CHECK_CALLED(Storage_Stat); 3017 ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid)); 3018 3019 lstrcpyW(buf, clsidW); 3020 StringFromGUID2(&CLSID_WineTestOld, buf+6, 39); 3021 3022 ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0, 3023 KEY_READ | KEY_WRITE | KEY_CREATE_SUB_KEY, NULL, &root, NULL); 3024 if(ret != ERROR_SUCCESS) { 3025 win_skip("not enough permissions to create CLSID key (%u)\n", ret); 3026 return; 3027 } 3028 3029 clsid = IID_WineTest; 3030 SET_EXPECT(Storage_Stat); 3031 hr = OleDoAutoConvert(&Storage, &clsid); 3032 ok(hr == REGDB_E_KEYMISSING, "OleDoAutoConvert returned %x\n", hr); 3033 CHECK_CALLED(Storage_Stat); 3034 ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid)); 3035 3036 hr = OleSetAutoConvert(&CLSID_WineTestOld, &CLSID_WineTest); 3037 ok_ole_success(hr, "OleSetAutoConvert"); 3038 3039 hr = OleGetAutoConvert(&CLSID_WineTestOld, &clsid); 3040 ok_ole_success(hr, "OleGetAutoConvert"); 3041 ok(IsEqualIID(&clsid, &CLSID_WineTest), "incorrect clsid: %s\n", wine_dbgstr_guid(&clsid)); 3042 3043 clsid = IID_WineTest; 3044 SET_EXPECT(Storage_Stat); 3045 SET_EXPECT(Storage_OpenStream_CompObj); 3046 SET_EXPECT(Storage_SetClass); 3047 SET_EXPECT(Storage_CreateStream_CompObj); 3048 SET_EXPECT(Storage_OpenStream_Ole); 3049 hr = OleDoAutoConvert(&Storage, &clsid); 3050 ok(hr == S_OK, "OleDoAutoConvert returned %x\n", hr); 3051 CHECK_CALLED(Storage_Stat); 3052 CHECK_CALLED(Storage_OpenStream_CompObj); 3053 CHECK_CALLED(Storage_SetClass); 3054 CHECK_CALLED(Storage_CreateStream_CompObj); 3055 CHECK_CALLED(Storage_OpenStream_Ole); 3056 ok(IsEqualIID(&clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(&clsid)); 3057 3058 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL); 3059 ok(hr == S_OK, "IStream_Seek returned %x\n", hr); 3060 hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL); 3061 ok(hr == S_OK, "IStream_Read returned %x\n", hr); 3062 ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1); 3063 ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version); 3064 ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]); 3065 ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1))); 3066 ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len); 3067 ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len); 3068 ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3); 3069 ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker); 3070 ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len); 3071 ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len); 3072 ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4); 3073 3074 hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL); 3075 ok(hr == S_OK, "IStream_Seek returned %x\n", hr); 3076 hr = IStream_Read(ole_stream, &ole_data, sizeof(ole_data), NULL); 3077 ok(hr == S_OK, "IStream_Read returned %x\n", hr); 3078 ok(ole_data.version == 0, "version = %x\n", ole_data.version); 3079 ok(ole_data.flags == 4, "flags = %x\n", ole_data.flags); 3080 for(i=2; i<sizeof(ole_data)/sizeof(DWORD); i++) 3081 ok(((DWORD*)&ole_data)[i] == 0, "ole_data[%d] = %x\n", i, ((DWORD*)&ole_data)[i]); 3082 3083 SET_EXPECT(Storage_OpenStream_Ole); 3084 hr = SetConvertStg(&Storage, TRUE); 3085 ok(hr == S_OK, "SetConvertStg returned %x\n", hr); 3086 CHECK_CALLED(Storage_OpenStream_Ole); 3087 3088 SET_EXPECT(Storage_OpenStream_CompObj); 3089 SET_EXPECT(Storage_Stat); 3090 SET_EXPECT(Storage_CreateStream_CompObj); 3091 hr = WriteFmtUserTypeStg(&Storage, 0, NULL); 3092 ok(hr == S_OK, "WriteFmtUserTypeStg returned %x\n", hr); 3093 todo_wine CHECK_CALLED(Storage_OpenStream_CompObj); 3094 CHECK_CALLED(Storage_Stat); 3095 CHECK_CALLED(Storage_CreateStream_CompObj); 3096 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL); 3097 ok(hr == S_OK, "IStream_Seek returned %x\n", hr); 3098 hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL); 3099 ok(hr == S_OK, "IStream_Read returned %x\n", hr); 3100 ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1); 3101 ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version); 3102 ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]); 3103 ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1))); 3104 ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len); 3105 ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len); 3106 ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3); 3107 ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker); 3108 ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len); 3109 ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len); 3110 ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4); 3111 3112 ret = IStream_Release(comp_obj_stream); 3113 ok(!ret, "comp_obj_stream was not freed\n"); 3114 ret = IStream_Release(ole_stream); 3115 ok(!ret, "ole_stream was not freed\n"); 3116 3117 ret = RegDeleteKeyA(root, "AutoConvertTo"); 3118 ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret); 3119 ret = RegDeleteKeyA(root, ""); 3120 ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret); 3121 RegCloseKey(root); 3122 } 3123 3124 START_TEST(ole2) 3125 { 3126 DWORD dwRegister; 3127 IStorage *pStorage; 3128 STATSTG statstg; 3129 HRESULT hr; 3130 3131 cf_test_1 = RegisterClipboardFormatA("cf_winetest_1"); 3132 cf_test_2 = RegisterClipboardFormatA("cf_winetest_2"); 3133 cf_test_3 = RegisterClipboardFormatA("cf_winetest_3"); 3134 3135 CoInitialize(NULL); 3136 3137 hr = CoRegisterClassObject(&CLSID_Equation3, (IUnknown *)&OleObjectCF, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister); 3138 ok_ole_success(hr, "CoRegisterClassObject"); 3139 3140 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage); 3141 ok_ole_success(hr, "StgCreateDocfile"); 3142 3143 test_OleCreate(pStorage); 3144 3145 hr = IStorage_Stat(pStorage, &statstg, STATFLAG_NONAME); 3146 ok_ole_success(hr, "IStorage_Stat"); 3147 ok(IsEqualCLSID(&CLSID_Equation3, &statstg.clsid), "Wrong CLSID in storage\n"); 3148 3149 test_OleLoad(pStorage); 3150 3151 IStorage_Release(pStorage); 3152 3153 hr = CoRevokeClassObject(dwRegister); 3154 ok_ole_success(hr, "CoRevokeClassObject"); 3155 3156 test_data_cache(); 3157 test_data_cache_dib_contents_stream( 0 ); 3158 test_data_cache_dib_contents_stream( 1 ); 3159 test_data_cache_bitmap(); 3160 test_data_cache_init(); 3161 test_data_cache_initnew(); 3162 test_default_handler(); 3163 test_runnable(); 3164 test_OleRun(); 3165 test_OleLockRunning(); 3166 test_OleDraw(); 3167 test_OleDoAutoConvert(); 3168 3169 CoUninitialize(); 3170 } 3171