1 /* 2 * Object Linking and Embedding Tests 3 * 4 * Copyright 2005 Robert Shearman 5 * Copyright 2017 Dmitry Timoshkov 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #define COBJMACROS 23 #define CONST_VTABLE 24 #define WIN32_LEAN_AND_MEAN 25 26 #include <stdarg.h> 27 28 #include "windef.h" 29 #include "winbase.h" 30 #include "wingdi.h" 31 #include "objbase.h" 32 #include "shlguid.h" 33 34 #include "wine/test.h" 35 36 #define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr) 37 38 #define DEFINE_EXPECT(func) \ 39 static BOOL expect_ ## func = FALSE, called_ ## func = FALSE 40 41 #define SET_EXPECT(func) \ 42 expect_ ## func = TRUE 43 44 #define CHECK_EXPECT2(func) \ 45 do { \ 46 ok(expect_ ##func, "unexpected call " #func "\n"); \ 47 called_ ## func = TRUE; \ 48 }while(0) 49 50 #define CHECK_EXPECT(func) \ 51 do { \ 52 CHECK_EXPECT2(func); \ 53 expect_ ## func = FALSE; \ 54 }while(0) 55 56 #define CHECK_CALLED(func) \ 57 do { \ 58 ok(called_ ## func, "expected " #func "\n"); \ 59 expect_ ## func = called_ ## func = FALSE; \ 60 }while(0) 61 62 DEFINE_EXPECT(Storage_Stat); 63 DEFINE_EXPECT(Storage_OpenStream_CompObj); 64 DEFINE_EXPECT(Storage_OpenStream_OlePres); 65 DEFINE_EXPECT(Storage_SetClass); 66 DEFINE_EXPECT(Storage_CreateStream_CompObj); 67 DEFINE_EXPECT(Storage_CreateStream_OlePres); 68 DEFINE_EXPECT(Storage_OpenStream_Ole); 69 DEFINE_EXPECT(Storage_DestroyElement); 70 71 static const CLSID *Storage_SetClass_CLSID; 72 static int Storage_DestroyElement_limit; 73 74 static IPersistStorage OleObjectPersistStg; 75 static IOleCache *cache; 76 static IRunnableObject *runnable; 77 78 static const CLSID CLSID_WineTestOld = 79 { /* 9474ba1a-258b-490b-bc13-516e9239acd0 */ 80 0x9474ba1a, 81 0x258b, 82 0x490b, 83 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xd0} 84 }; 85 86 static const CLSID CLSID_WineTest = 87 { /* 9474ba1a-258b-490b-bc13-516e9239ace0 */ 88 0x9474ba1a, 89 0x258b, 90 0x490b, 91 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe0} 92 }; 93 94 static const IID IID_WineTest = 95 { /* 9474ba1a-258b-490b-bc13-516e9239ace1 */ 96 0x9474ba1a, 97 0x258b, 98 0x490b, 99 {0xbc, 0x13, 0x51, 0x6e, 0x92, 0x39, 0xac, 0xe1} 100 }; 101 102 #define TEST_OPTIONAL 0x1 103 #define TEST_TODO 0x2 104 105 struct expected_method 106 { 107 const char *method; 108 unsigned int flags; 109 FORMATETC fmt; 110 }; 111 112 static const struct expected_method *expected_method_list; 113 static FORMATETC *g_expected_fetc = NULL; 114 115 static BOOL g_showRunnable = TRUE; 116 static BOOL g_isRunning = TRUE; 117 static HRESULT g_GetMiscStatusFailsWith = S_OK; 118 static HRESULT g_QIFailsWith; 119 120 static UINT cf_test_1, cf_test_2, cf_test_3; 121 122 static FORMATETC *g_dataobject_fmts; 123 124 /**************************************************************************** 125 * PresentationDataHeader 126 * 127 * This structure represents the header of the \002OlePresXXX stream in 128 * the OLE object storage. 129 */ 130 typedef struct PresentationDataHeader 131 { 132 /* clipformat: 133 * - standard clipformat: 134 * DWORD length = 0xffffffff; 135 * DWORD cfFormat; 136 * - or custom clipformat: 137 * DWORD length; 138 * CHAR format_name[length]; (null-terminated) 139 */ 140 DWORD tdSize; /* This is actually a truncated DVTARGETDEVICE, if tdSize > sizeof(DWORD) 141 then there are tdSize - sizeof(DWORD) more bytes before dvAspect */ 142 DVASPECT dvAspect; 143 DWORD lindex; 144 DWORD advf; 145 DWORD unknown7; /* 0 */ 146 DWORD dwObjectExtentX; 147 DWORD dwObjectExtentY; 148 DWORD dwSize; 149 } PresentationDataHeader; 150 151 #ifdef __REACTOS__ 152 static inline void check_expected_method_fmt(const char *method_name, const FORMATETC *fmt) 153 #else 154 static void inline check_expected_method_fmt(const char *method_name, const FORMATETC *fmt) 155 #endif 156 { 157 trace("%s\n", method_name); 158 ok(expected_method_list->method != NULL, "Extra method %s called\n", method_name); 159 if (!strcmp(expected_method_list->method, "WINE_EXTRA")) 160 { 161 todo_wine ok(0, "Too many method calls.\n"); 162 return; 163 } 164 if (expected_method_list->method) 165 { 166 while (expected_method_list->flags & TEST_OPTIONAL && 167 strcmp(expected_method_list->method, method_name) != 0) 168 expected_method_list++; 169 todo_wine_if (expected_method_list->flags & TEST_TODO) 170 { 171 ok(!strcmp(expected_method_list->method, method_name), 172 "Expected %s to be called instead of %s\n", 173 expected_method_list->method, method_name); 174 if (fmt) 175 { 176 ok(fmt->cfFormat == expected_method_list->fmt.cfFormat, "got cf %04x vs %04x\n", 177 fmt->cfFormat, expected_method_list->fmt.cfFormat ); 178 ok(fmt->dwAspect == expected_method_list->fmt.dwAspect, "got aspect %d vs %d\n", 179 fmt->dwAspect, expected_method_list->fmt.dwAspect ); 180 ok(fmt->lindex == expected_method_list->fmt.lindex, "got lindex %d vs %d\n", 181 fmt->lindex, expected_method_list->fmt.lindex ); 182 ok(fmt->tymed == expected_method_list->fmt.tymed, "got tymed %d vs %d\n", 183 fmt->tymed, expected_method_list->fmt.tymed ); 184 } 185 } 186 expected_method_list++; 187 } 188 } 189 190 #define CHECK_EXPECTED_METHOD(method_name) check_expected_method_fmt(method_name, NULL) 191 #define CHECK_EXPECTED_METHOD_FMT(method_name, fmt) check_expected_method_fmt(method_name, fmt) 192 193 #define CHECK_NO_EXTRA_METHODS() \ 194 do { \ 195 while (expected_method_list->flags & TEST_OPTIONAL) \ 196 expected_method_list++; \ 197 ok(!expected_method_list->method, "Method sequence starting from %s not called\n", expected_method_list->method); \ 198 } while (0) 199 200 /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */ 201 static const BYTE dib[] = 202 { 203 0x28, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 204 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 206 0xc8, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 208 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 209 }; 210 211 static void create_dib( STGMEDIUM *med ) 212 { 213 void *ptr; 214 215 med->tymed = TYMED_HGLOBAL; 216 U(med)->hGlobal = GlobalAlloc( GMEM_MOVEABLE, sizeof(dib) ); 217 ptr = GlobalLock( U(med)->hGlobal ); 218 memcpy( ptr, dib, sizeof(dib) ); 219 GlobalUnlock( U(med)->hGlobal ); 220 med->pUnkForRelease = NULL; 221 } 222 223 static void create_bitmap( STGMEDIUM *med ) 224 { 225 med->tymed = TYMED_GDI; 226 U(med)->hBitmap = CreateBitmap( 1, 1, 1, 1, NULL ); 227 med->pUnkForRelease = NULL; 228 } 229 230 static void create_emf(STGMEDIUM *med) 231 { 232 HDC hdc = CreateEnhMetaFileW(NULL, NULL, NULL, NULL); 233 234 Rectangle(hdc, 0, 0, 150, 300); 235 med->tymed = TYMED_ENHMF; 236 U(med)->hEnhMetaFile = CloseEnhMetaFile(hdc); 237 med->pUnkForRelease = NULL; 238 } 239 240 static void create_mfpict(STGMEDIUM *med) 241 { 242 METAFILEPICT *mf; 243 HDC hdc = CreateMetaFileW(NULL); 244 245 Rectangle(hdc, 0, 0, 100, 200); 246 247 med->tymed = TYMED_MFPICT; 248 U(med)->hMetaFilePict = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILEPICT)); 249 mf = GlobalLock(U(med)->hMetaFilePict); 250 mf->mm = MM_ANISOTROPIC; 251 mf->xExt = 100; 252 mf->yExt = 200; 253 mf->hMF = CloseMetaFile(hdc); 254 GlobalUnlock(U(med)->hMetaFilePict); 255 med->pUnkForRelease = NULL; 256 } 257 258 static void create_text(STGMEDIUM *med) 259 { 260 HGLOBAL handle; 261 char *p; 262 263 handle = GlobalAlloc(GMEM_DDESHARE|GMEM_MOVEABLE, 5); 264 p = GlobalLock(handle); 265 strcpy(p, "test"); 266 GlobalUnlock(handle); 267 268 med->tymed = TYMED_HGLOBAL; 269 U(med)->hGlobal = handle; 270 med->pUnkForRelease = NULL; 271 } 272 273 static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv) 274 { 275 CHECK_EXPECTED_METHOD("OleObject_QueryInterface"); 276 277 *ppv = NULL; 278 279 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IOleObject)) 280 *ppv = iface; 281 else if (IsEqualIID(riid, &IID_IPersistStorage)) 282 *ppv = &OleObjectPersistStg; 283 else if (IsEqualIID(riid, &IID_IOleCache)) 284 *ppv = cache; 285 else if (IsEqualIID(riid, &IID_IRunnableObject) && g_showRunnable) 286 *ppv = runnable; 287 else if (IsEqualIID(riid, &IID_WineTest)) 288 return g_QIFailsWith; 289 290 if(*ppv) { 291 IUnknown_AddRef((IUnknown*)*ppv); 292 return S_OK; 293 } 294 295 trace("OleObject_QueryInterface: returning E_NOINTERFACE\n"); 296 return E_NOINTERFACE; 297 } 298 299 static ULONG WINAPI OleObject_AddRef(IOleObject *iface) 300 { 301 CHECK_EXPECTED_METHOD("OleObject_AddRef"); 302 return 2; 303 } 304 305 static ULONG WINAPI OleObject_Release(IOleObject *iface) 306 { 307 CHECK_EXPECTED_METHOD("OleObject_Release"); 308 return 1; 309 } 310 311 static HRESULT WINAPI OleObject_SetClientSite 312 ( 313 IOleObject *iface, 314 IOleClientSite *pClientSite 315 ) 316 { 317 CHECK_EXPECTED_METHOD("OleObject_SetClientSite"); 318 return S_OK; 319 } 320 321 static HRESULT WINAPI OleObject_GetClientSite 322 ( 323 IOleObject *iface, 324 IOleClientSite **ppClientSite 325 ) 326 { 327 CHECK_EXPECTED_METHOD("OleObject_GetClientSite"); 328 return E_NOTIMPL; 329 } 330 331 static HRESULT WINAPI OleObject_SetHostNames 332 ( 333 IOleObject *iface, 334 LPCOLESTR szContainerApp, 335 LPCOLESTR szContainerObj 336 ) 337 { 338 CHECK_EXPECTED_METHOD("OleObject_SetHostNames"); 339 return S_OK; 340 } 341 342 static HRESULT WINAPI OleObject_Close 343 ( 344 IOleObject *iface, 345 DWORD dwSaveOption 346 ) 347 { 348 CHECK_EXPECTED_METHOD("OleObject_Close"); 349 return S_OK; 350 } 351 352 static HRESULT WINAPI OleObject_SetMoniker 353 ( 354 IOleObject *iface, 355 DWORD dwWhichMoniker, 356 IMoniker *pmk 357 ) 358 { 359 CHECK_EXPECTED_METHOD("OleObject_SetMoniker"); 360 return S_OK; 361 } 362 363 static HRESULT WINAPI OleObject_GetMoniker 364 ( 365 IOleObject *iface, 366 DWORD dwAssign, 367 DWORD dwWhichMoniker, 368 IMoniker **ppmk 369 ) 370 { 371 CHECK_EXPECTED_METHOD("OleObject_GetMoniker"); 372 return S_OK; 373 } 374 375 static HRESULT WINAPI OleObject_InitFromData 376 ( 377 IOleObject *iface, 378 IDataObject *pDataObject, 379 BOOL fCreation, 380 DWORD dwReserved 381 ) 382 { 383 CHECK_EXPECTED_METHOD("OleObject_InitFromData"); 384 return S_OK; 385 } 386 387 static HRESULT WINAPI OleObject_GetClipboardData 388 ( 389 IOleObject *iface, 390 DWORD dwReserved, 391 IDataObject **ppDataObject 392 ) 393 { 394 CHECK_EXPECTED_METHOD("OleObject_GetClipboardData"); 395 return E_NOTIMPL; 396 } 397 398 static HRESULT WINAPI OleObject_DoVerb 399 ( 400 IOleObject *iface, 401 LONG iVerb, 402 LPMSG lpmsg, 403 IOleClientSite *pActiveSite, 404 LONG lindex, 405 HWND hwndParent, 406 LPCRECT lprcPosRect 407 ) 408 { 409 CHECK_EXPECTED_METHOD("OleObject_DoVerb"); 410 return S_OK; 411 } 412 413 static HRESULT WINAPI OleObject_EnumVerbs 414 ( 415 IOleObject *iface, 416 IEnumOLEVERB **ppEnumOleVerb 417 ) 418 { 419 CHECK_EXPECTED_METHOD("OleObject_EnumVerbs"); 420 return E_NOTIMPL; 421 } 422 423 static HRESULT WINAPI OleObject_Update 424 ( 425 IOleObject *iface 426 ) 427 { 428 CHECK_EXPECTED_METHOD("OleObject_Update"); 429 return S_OK; 430 } 431 432 static HRESULT WINAPI OleObject_IsUpToDate 433 ( 434 IOleObject *iface 435 ) 436 { 437 CHECK_EXPECTED_METHOD("OleObject_IsUpToDate"); 438 return S_OK; 439 } 440 441 static HRESULT WINAPI OleObject_GetUserClassID 442 ( 443 IOleObject *iface, 444 CLSID *pClsid 445 ) 446 { 447 CHECK_EXPECTED_METHOD("OleObject_GetUserClassID"); 448 return E_NOTIMPL; 449 } 450 451 static HRESULT WINAPI OleObject_GetUserType 452 ( 453 IOleObject *iface, 454 DWORD dwFormOfType, 455 LPOLESTR *pszUserType 456 ) 457 { 458 CHECK_EXPECTED_METHOD("OleObject_GetUserType"); 459 return E_NOTIMPL; 460 } 461 462 static HRESULT WINAPI OleObject_SetExtent 463 ( 464 IOleObject *iface, 465 DWORD dwDrawAspect, 466 SIZEL *psizel 467 ) 468 { 469 CHECK_EXPECTED_METHOD("OleObject_SetExtent"); 470 return S_OK; 471 } 472 473 static HRESULT WINAPI OleObject_GetExtent 474 ( 475 IOleObject *iface, 476 DWORD dwDrawAspect, 477 SIZEL *psizel 478 ) 479 { 480 CHECK_EXPECTED_METHOD("OleObject_GetExtent"); 481 return E_NOTIMPL; 482 } 483 484 static HRESULT WINAPI OleObject_Advise 485 ( 486 IOleObject *iface, 487 IAdviseSink *pAdvSink, 488 DWORD *pdwConnection 489 ) 490 { 491 CHECK_EXPECTED_METHOD("OleObject_Advise"); 492 return S_OK; 493 } 494 495 static HRESULT WINAPI OleObject_Unadvise 496 ( 497 IOleObject *iface, 498 DWORD dwConnection 499 ) 500 { 501 CHECK_EXPECTED_METHOD("OleObject_Unadvise"); 502 return S_OK; 503 } 504 505 static HRESULT WINAPI OleObject_EnumAdvise 506 ( 507 IOleObject *iface, 508 IEnumSTATDATA **ppenumAdvise 509 ) 510 { 511 CHECK_EXPECTED_METHOD("OleObject_EnumAdvise"); 512 return E_NOTIMPL; 513 } 514 515 static HRESULT WINAPI OleObject_GetMiscStatus 516 ( 517 IOleObject *iface, 518 DWORD aspect, 519 DWORD *pdwStatus 520 ) 521 { 522 CHECK_EXPECTED_METHOD("OleObject_GetMiscStatus"); 523 524 ok(aspect == DVASPECT_CONTENT, "got aspect %d\n", aspect); 525 526 if (g_GetMiscStatusFailsWith == S_OK) 527 { 528 *pdwStatus = OLEMISC_RECOMPOSEONRESIZE; 529 return S_OK; 530 } 531 else 532 { 533 *pdwStatus = 0x1234; 534 return g_GetMiscStatusFailsWith; 535 } 536 } 537 538 static HRESULT WINAPI OleObject_SetColorScheme 539 ( 540 IOleObject *iface, 541 LOGPALETTE *pLogpal 542 ) 543 { 544 CHECK_EXPECTED_METHOD("OleObject_SetColorScheme"); 545 return E_NOTIMPL; 546 } 547 548 static const IOleObjectVtbl OleObjectVtbl = 549 { 550 OleObject_QueryInterface, 551 OleObject_AddRef, 552 OleObject_Release, 553 OleObject_SetClientSite, 554 OleObject_GetClientSite, 555 OleObject_SetHostNames, 556 OleObject_Close, 557 OleObject_SetMoniker, 558 OleObject_GetMoniker, 559 OleObject_InitFromData, 560 OleObject_GetClipboardData, 561 OleObject_DoVerb, 562 OleObject_EnumVerbs, 563 OleObject_Update, 564 OleObject_IsUpToDate, 565 OleObject_GetUserClassID, 566 OleObject_GetUserType, 567 OleObject_SetExtent, 568 OleObject_GetExtent, 569 OleObject_Advise, 570 OleObject_Unadvise, 571 OleObject_EnumAdvise, 572 OleObject_GetMiscStatus, 573 OleObject_SetColorScheme 574 }; 575 576 static IOleObject OleObject = { &OleObjectVtbl }; 577 578 static HRESULT WINAPI OleObjectPersistStg_QueryInterface(IPersistStorage *iface, REFIID riid, void **ppv) 579 { 580 trace("OleObjectPersistStg_QueryInterface\n"); 581 return IOleObject_QueryInterface(&OleObject, riid, ppv); 582 } 583 584 static ULONG WINAPI OleObjectPersistStg_AddRef(IPersistStorage *iface) 585 { 586 CHECK_EXPECTED_METHOD("OleObjectPersistStg_AddRef"); 587 return 2; 588 } 589 590 static ULONG WINAPI OleObjectPersistStg_Release(IPersistStorage *iface) 591 { 592 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Release"); 593 return 1; 594 } 595 596 static HRESULT WINAPI OleObjectPersistStg_GetClassId(IPersistStorage *iface, CLSID *clsid) 597 { 598 CHECK_EXPECTED_METHOD("OleObjectPersistStg_GetClassId"); 599 return E_NOTIMPL; 600 } 601 602 static HRESULT WINAPI OleObjectPersistStg_IsDirty 603 ( 604 IPersistStorage *iface 605 ) 606 { 607 CHECK_EXPECTED_METHOD("OleObjectPersistStg_IsDirty"); 608 return S_OK; 609 } 610 611 static HRESULT WINAPI OleObjectPersistStg_InitNew 612 ( 613 IPersistStorage *iface, 614 IStorage *pStg 615 ) 616 { 617 CHECK_EXPECTED_METHOD("OleObjectPersistStg_InitNew"); 618 return S_OK; 619 } 620 621 static HRESULT WINAPI OleObjectPersistStg_Load 622 ( 623 IPersistStorage *iface, 624 IStorage *pStg 625 ) 626 { 627 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Load"); 628 return S_OK; 629 } 630 631 static HRESULT WINAPI OleObjectPersistStg_Save 632 ( 633 IPersistStorage *iface, 634 IStorage *pStgSave, 635 BOOL fSameAsLoad 636 ) 637 { 638 CHECK_EXPECTED_METHOD("OleObjectPersistStg_Save"); 639 return S_OK; 640 } 641 642 static HRESULT WINAPI OleObjectPersistStg_SaveCompleted 643 ( 644 IPersistStorage *iface, 645 IStorage *pStgNew 646 ) 647 { 648 CHECK_EXPECTED_METHOD("OleObjectPersistStg_SaveCompleted"); 649 return S_OK; 650 } 651 652 static HRESULT WINAPI OleObjectPersistStg_HandsOffStorage 653 ( 654 IPersistStorage *iface 655 ) 656 { 657 CHECK_EXPECTED_METHOD("OleObjectPersistStg_HandsOffStorage"); 658 return S_OK; 659 } 660 661 static const IPersistStorageVtbl OleObjectPersistStgVtbl = 662 { 663 OleObjectPersistStg_QueryInterface, 664 OleObjectPersistStg_AddRef, 665 OleObjectPersistStg_Release, 666 OleObjectPersistStg_GetClassId, 667 OleObjectPersistStg_IsDirty, 668 OleObjectPersistStg_InitNew, 669 OleObjectPersistStg_Load, 670 OleObjectPersistStg_Save, 671 OleObjectPersistStg_SaveCompleted, 672 OleObjectPersistStg_HandsOffStorage 673 }; 674 675 static IPersistStorage OleObjectPersistStg = { &OleObjectPersistStgVtbl }; 676 677 static HRESULT WINAPI OleObjectCache_QueryInterface(IOleCache *iface, REFIID riid, void **ppv) 678 { 679 return IOleObject_QueryInterface(&OleObject, riid, ppv); 680 } 681 682 static ULONG WINAPI OleObjectCache_AddRef(IOleCache *iface) 683 { 684 CHECK_EXPECTED_METHOD("OleObjectCache_AddRef"); 685 return 2; 686 } 687 688 static ULONG WINAPI OleObjectCache_Release(IOleCache *iface) 689 { 690 CHECK_EXPECTED_METHOD("OleObjectCache_Release"); 691 return 1; 692 } 693 694 static HRESULT WINAPI OleObjectCache_Cache 695 ( 696 IOleCache *iface, 697 FORMATETC *pformatetc, 698 DWORD advf, 699 DWORD *pdwConnection 700 ) 701 { 702 CHECK_EXPECTED_METHOD("OleObjectCache_Cache"); 703 if (g_expected_fetc) { 704 ok(pformatetc != NULL, "pformatetc should not be NULL\n"); 705 if (pformatetc) { 706 ok(pformatetc->cfFormat == g_expected_fetc->cfFormat, 707 "cfFormat: %x\n", pformatetc->cfFormat); 708 ok((pformatetc->ptd != NULL) == (g_expected_fetc->ptd != NULL), 709 "ptd: %p\n", pformatetc->ptd); 710 ok(pformatetc->dwAspect == g_expected_fetc->dwAspect, 711 "dwAspect: %x\n", pformatetc->dwAspect); 712 ok(pformatetc->lindex == g_expected_fetc->lindex, 713 "lindex: %x\n", pformatetc->lindex); 714 ok(pformatetc->tymed == g_expected_fetc->tymed, 715 "tymed: %x\n", pformatetc->tymed); 716 } 717 } else 718 ok(pformatetc == NULL, "pformatetc should be NULL\n"); 719 return S_OK; 720 } 721 722 static HRESULT WINAPI OleObjectCache_Uncache 723 ( 724 IOleCache *iface, 725 DWORD dwConnection 726 ) 727 { 728 CHECK_EXPECTED_METHOD("OleObjectCache_Uncache"); 729 return S_OK; 730 } 731 732 static HRESULT WINAPI OleObjectCache_EnumCache 733 ( 734 IOleCache *iface, 735 IEnumSTATDATA **ppenumSTATDATA 736 ) 737 { 738 CHECK_EXPECTED_METHOD("OleObjectCache_EnumCache"); 739 return S_OK; 740 } 741 742 743 static HRESULT WINAPI OleObjectCache_InitCache 744 ( 745 IOleCache *iface, 746 IDataObject *pDataObject 747 ) 748 { 749 CHECK_EXPECTED_METHOD("OleObjectCache_InitCache"); 750 return S_OK; 751 } 752 753 754 static HRESULT WINAPI OleObjectCache_SetData 755 ( 756 IOleCache *iface, 757 FORMATETC *pformatetc, 758 STGMEDIUM *pmedium, 759 BOOL fRelease 760 ) 761 { 762 CHECK_EXPECTED_METHOD("OleObjectCache_SetData"); 763 return S_OK; 764 } 765 766 767 static const IOleCacheVtbl OleObjectCacheVtbl = 768 { 769 OleObjectCache_QueryInterface, 770 OleObjectCache_AddRef, 771 OleObjectCache_Release, 772 OleObjectCache_Cache, 773 OleObjectCache_Uncache, 774 OleObjectCache_EnumCache, 775 OleObjectCache_InitCache, 776 OleObjectCache_SetData 777 }; 778 779 static IOleCache OleObjectCache = { &OleObjectCacheVtbl }; 780 781 static HRESULT WINAPI OleObjectCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) 782 { 783 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory)) 784 { 785 *ppv = iface; 786 IClassFactory_AddRef(iface); 787 return S_OK; 788 } 789 *ppv = NULL; 790 return E_NOINTERFACE; 791 } 792 793 static ULONG WINAPI OleObjectCF_AddRef(IClassFactory *iface) 794 { 795 return 2; 796 } 797 798 static ULONG WINAPI OleObjectCF_Release(IClassFactory *iface) 799 { 800 return 1; 801 } 802 803 static HRESULT WINAPI OleObjectCF_CreateInstance(IClassFactory *iface, IUnknown *punkOuter, REFIID riid, void **ppv) 804 { 805 return IOleObject_QueryInterface(&OleObject, riid, ppv); 806 } 807 808 static HRESULT WINAPI OleObjectCF_LockServer(IClassFactory *iface, BOOL lock) 809 { 810 return S_OK; 811 } 812 813 static const IClassFactoryVtbl OleObjectCFVtbl = 814 { 815 OleObjectCF_QueryInterface, 816 OleObjectCF_AddRef, 817 OleObjectCF_Release, 818 OleObjectCF_CreateInstance, 819 OleObjectCF_LockServer 820 }; 821 822 static IClassFactory OleObjectCF = { &OleObjectCFVtbl }; 823 824 static HRESULT WINAPI OleObjectRunnable_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv) 825 { 826 return IOleObject_QueryInterface(&OleObject, riid, ppv); 827 } 828 829 static ULONG WINAPI OleObjectRunnable_AddRef(IRunnableObject *iface) 830 { 831 CHECK_EXPECTED_METHOD("OleObjectRunnable_AddRef"); 832 return 2; 833 } 834 835 static ULONG WINAPI OleObjectRunnable_Release(IRunnableObject *iface) 836 { 837 CHECK_EXPECTED_METHOD("OleObjectRunnable_Release"); 838 return 1; 839 } 840 841 static HRESULT WINAPI OleObjectRunnable_GetRunningClass( 842 IRunnableObject *iface, 843 LPCLSID lpClsid) 844 { 845 CHECK_EXPECTED_METHOD("OleObjectRunnable_GetRunningClass"); 846 return E_NOTIMPL; 847 } 848 849 static HRESULT WINAPI OleObjectRunnable_Run( 850 IRunnableObject *iface, 851 LPBINDCTX pbc) 852 { 853 CHECK_EXPECTED_METHOD("OleObjectRunnable_Run"); 854 return S_OK; 855 } 856 857 static BOOL WINAPI OleObjectRunnable_IsRunning(IRunnableObject *iface) 858 { 859 CHECK_EXPECTED_METHOD("OleObjectRunnable_IsRunning"); 860 return g_isRunning; 861 } 862 863 static HRESULT WINAPI OleObjectRunnable_LockRunning( 864 IRunnableObject *iface, 865 BOOL fLock, 866 BOOL fLastUnlockCloses) 867 { 868 CHECK_EXPECTED_METHOD("OleObjectRunnable_LockRunning"); 869 return S_OK; 870 } 871 872 static HRESULT WINAPI OleObjectRunnable_SetContainedObject( 873 IRunnableObject *iface, 874 BOOL fContained) 875 { 876 CHECK_EXPECTED_METHOD("OleObjectRunnable_SetContainedObject"); 877 return S_OK; 878 } 879 880 static const IRunnableObjectVtbl OleObjectRunnableVtbl = 881 { 882 OleObjectRunnable_QueryInterface, 883 OleObjectRunnable_AddRef, 884 OleObjectRunnable_Release, 885 OleObjectRunnable_GetRunningClass, 886 OleObjectRunnable_Run, 887 OleObjectRunnable_IsRunning, 888 OleObjectRunnable_LockRunning, 889 OleObjectRunnable_SetContainedObject 890 }; 891 892 static IRunnableObject OleObjectRunnable = { &OleObjectRunnableVtbl }; 893 894 static const CLSID CLSID_Equation3 = {0x0002CE02, 0x0000, 0x0000, {0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46} }; 895 896 static HRESULT WINAPI viewobject_QueryInterface(IViewObject *iface, REFIID riid, void **obj) 897 { 898 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IViewObject)) 899 { 900 *obj = iface; 901 return S_OK; 902 } 903 904 *obj = NULL; 905 return E_NOINTERFACE; 906 } 907 908 static ULONG WINAPI viewobject_AddRef(IViewObject *iface) 909 { 910 return 2; 911 } 912 913 static ULONG WINAPI viewobject_Release(IViewObject *iface) 914 { 915 return 1; 916 } 917 918 static HRESULT WINAPI viewobject_Draw(IViewObject *iface, DWORD aspect, LONG index, 919 void *paspect, DVTARGETDEVICE *ptd, HDC hdcTargetDev, HDC hdcDraw, 920 LPCRECTL bounds, LPCRECTL wbounds, BOOL (STDMETHODCALLTYPE *pfnContinue)(ULONG_PTR dwContinue), 921 ULONG_PTR dwContinue) 922 { 923 ok(index == -1, "index=%d\n", index); 924 return S_OK; 925 } 926 927 static HRESULT WINAPI viewobject_GetColorSet(IViewObject *iface, DWORD draw_aspect, LONG index, 928 void *aspect, DVTARGETDEVICE *ptd, HDC hicTargetDev, LOGPALETTE **colorset) 929 { 930 ok(0, "unexpected call GetColorSet\n"); 931 return E_NOTIMPL; 932 } 933 934 static HRESULT WINAPI viewobject_Freeze(IViewObject *iface, DWORD draw_aspect, LONG index, 935 void *aspect, DWORD *freeze) 936 { 937 ok(0, "unexpected call Freeze\n"); 938 return E_NOTIMPL; 939 } 940 941 static HRESULT WINAPI viewobject_Unfreeze(IViewObject *iface, DWORD freeze) 942 { 943 ok(0, "unexpected call Unfreeze\n"); 944 return E_NOTIMPL; 945 } 946 947 static HRESULT WINAPI viewobject_SetAdvise(IViewObject *iface, DWORD aspects, DWORD advf, IAdviseSink *sink) 948 { 949 ok(0, "unexpected call SetAdvise\n"); 950 return E_NOTIMPL; 951 } 952 953 static HRESULT WINAPI viewobject_GetAdvise(IViewObject *iface, DWORD *aspects, DWORD *advf, 954 IAdviseSink **sink) 955 { 956 ok(0, "unexpected call GetAdvise\n"); 957 return E_NOTIMPL; 958 } 959 960 static const struct IViewObjectVtbl viewobjectvtbl = { 961 viewobject_QueryInterface, 962 viewobject_AddRef, 963 viewobject_Release, 964 viewobject_Draw, 965 viewobject_GetColorSet, 966 viewobject_Freeze, 967 viewobject_Unfreeze, 968 viewobject_SetAdvise, 969 viewobject_GetAdvise 970 }; 971 972 static IViewObject viewobject = { &viewobjectvtbl }; 973 974 static void test_OleCreate(IStorage *pStorage) 975 { 976 HRESULT hr; 977 IOleObject *pObject; 978 FORMATETC formatetc; 979 static const struct expected_method methods_olerender_none[] = 980 { 981 { "OleObject_QueryInterface", 0 }, 982 { "OleObject_AddRef", 0 }, 983 { "OleObject_QueryInterface", 0 }, 984 { "OleObject_AddRef", TEST_OPTIONAL }, 985 { "OleObject_Release", TEST_OPTIONAL }, 986 { "OleObject_QueryInterface", TEST_OPTIONAL }, 987 { "OleObjectPersistStg_AddRef", 0 }, 988 { "OleObjectPersistStg_InitNew", 0 }, 989 { "OleObjectPersistStg_Release", 0 }, 990 { "OleObject_Release", 0 }, 991 { "OleObject_Release", TEST_OPTIONAL }, 992 { NULL, 0 } 993 }; 994 static const struct expected_method methods_olerender_draw[] = 995 { 996 { "OleObject_QueryInterface", 0 }, 997 { "OleObject_AddRef", 0 }, 998 { "OleObject_QueryInterface", 0 }, 999 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ }, 1000 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 1001 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ }, 1002 { "OleObjectPersistStg_AddRef", 0 }, 1003 { "OleObjectPersistStg_InitNew", 0 }, 1004 { "OleObjectPersistStg_Release", 0 }, 1005 { "OleObject_QueryInterface", 0 }, 1006 { "OleObjectRunnable_AddRef", 0 }, 1007 { "OleObjectRunnable_Run", 0 }, 1008 { "OleObjectRunnable_Release", 0 }, 1009 { "OleObject_QueryInterface", 0 }, 1010 { "OleObjectCache_AddRef", 0 }, 1011 { "OleObjectCache_Cache", 0 }, 1012 { "OleObjectCache_Release", 0 }, 1013 { "OleObject_Release", 0 }, 1014 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 1015 { NULL, 0 } 1016 }; 1017 static const struct expected_method methods_olerender_draw_with_site[] = 1018 { 1019 { "OleObject_QueryInterface", 0 }, 1020 { "OleObject_AddRef", 0 }, 1021 { "OleObject_QueryInterface", 0 }, 1022 { "OleObject_AddRef", 0 }, 1023 { "OleObject_GetMiscStatus", 0 }, 1024 { "OleObject_QueryInterface", 0 }, 1025 { "OleObjectPersistStg_AddRef", 0 }, 1026 { "OleObjectPersistStg_InitNew", 0 }, 1027 { "OleObjectPersistStg_Release", 0 }, 1028 { "OleObject_SetClientSite", 0 }, 1029 { "OleObject_Release", 0 }, 1030 { "OleObject_QueryInterface", 0 }, 1031 { "OleObjectRunnable_AddRef", 0 }, 1032 { "OleObjectRunnable_Run", 0 }, 1033 { "OleObjectRunnable_Release", 0 }, 1034 { "OleObject_QueryInterface", 0 }, 1035 { "OleObjectCache_AddRef", 0 }, 1036 { "OleObjectCache_Cache", 0 }, 1037 { "OleObjectCache_Release", 0 }, 1038 { "OleObject_Release", 0 }, 1039 { NULL, 0 } 1040 }; 1041 static const struct expected_method methods_olerender_format[] = 1042 { 1043 { "OleObject_QueryInterface", 0 }, 1044 { "OleObject_AddRef", 0 }, 1045 { "OleObject_QueryInterface", 0 }, 1046 { "OleObject_AddRef", 0 }, 1047 { "OleObject_GetMiscStatus", 0 }, 1048 { "OleObject_QueryInterface", 0 }, 1049 { "OleObjectPersistStg_AddRef", 0 }, 1050 { "OleObjectPersistStg_InitNew", 0 }, 1051 { "OleObjectPersistStg_Release", 0 }, 1052 { "OleObject_SetClientSite", 0 }, 1053 { "OleObject_Release", 0 }, 1054 { "OleObject_QueryInterface", 0 }, 1055 { "OleObjectRunnable_AddRef", 0 }, 1056 { "OleObjectRunnable_Run", 0 }, 1057 { "OleObjectRunnable_Release", 0 }, 1058 { "OleObject_QueryInterface", 0 }, 1059 { "OleObjectCache_AddRef", 0 }, 1060 { "OleObjectCache_Cache", 0 }, 1061 { "OleObjectCache_Release", 0 }, 1062 { "OleObject_Release", 0 }, 1063 { NULL, 0 } 1064 }; 1065 static const struct expected_method methods_olerender_asis[] = 1066 { 1067 { "OleObject_QueryInterface", 0 }, 1068 { "OleObject_AddRef", 0 }, 1069 { "OleObject_QueryInterface", 0 }, 1070 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ }, 1071 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 1072 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ }, 1073 { "OleObjectPersistStg_AddRef", 0 }, 1074 { "OleObjectPersistStg_InitNew", 0 }, 1075 { "OleObjectPersistStg_Release", 0 }, 1076 { "OleObject_Release", 0 }, 1077 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 1078 { NULL, 0 } 1079 }; 1080 static const struct expected_method methods_olerender_draw_no_runnable[] = 1081 { 1082 { "OleObject_QueryInterface", 0 }, 1083 { "OleObject_AddRef", 0 }, 1084 { "OleObject_QueryInterface", 0 }, 1085 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ }, 1086 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 1087 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ }, 1088 { "OleObjectPersistStg_AddRef", 0 }, 1089 { "OleObjectPersistStg_InitNew", 0 }, 1090 { "OleObjectPersistStg_Release", 0 }, 1091 { "OleObject_QueryInterface", 0 }, 1092 { "OleObject_QueryInterface", 0 }, 1093 { "OleObjectCache_AddRef", 0 }, 1094 { "OleObjectCache_Cache", 0 }, 1095 { "OleObjectCache_Release", 0 }, 1096 { "OleObject_Release", 0 }, 1097 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 1098 { NULL, 0 }, 1099 }; 1100 static const struct expected_method methods_olerender_draw_no_cache[] = 1101 { 1102 { "OleObject_QueryInterface", 0 }, 1103 { "OleObject_AddRef", 0 }, 1104 { "OleObject_QueryInterface", 0 }, 1105 { "OleObject_AddRef", TEST_OPTIONAL /* NT4 only */ }, 1106 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 1107 { "OleObject_QueryInterface", TEST_OPTIONAL /* NT4 only */ }, 1108 { "OleObjectPersistStg_AddRef", 0 }, 1109 { "OleObjectPersistStg_InitNew", 0 }, 1110 { "OleObjectPersistStg_Release", 0 }, 1111 { "OleObject_QueryInterface", 0 }, 1112 { "OleObjectRunnable_AddRef", 0 }, 1113 { "OleObjectRunnable_Run", 0 }, 1114 { "OleObjectRunnable_Release", 0 }, 1115 { "OleObject_QueryInterface", 0 }, 1116 { "OleObject_Release", 0 }, 1117 { "OleObject_Release", TEST_OPTIONAL /* NT4 only */ }, 1118 { NULL, 0 } 1119 }; 1120 1121 g_expected_fetc = &formatetc; 1122 formatetc.cfFormat = 0; 1123 formatetc.ptd = NULL; 1124 formatetc.dwAspect = DVASPECT_CONTENT; 1125 formatetc.lindex = -1; 1126 formatetc.tymed = TYMED_NULL; 1127 runnable = &OleObjectRunnable; 1128 cache = &OleObjectCache; 1129 expected_method_list = methods_olerender_none; 1130 trace("OleCreate with OLERENDER_NONE:\n"); 1131 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_NONE, NULL, NULL, pStorage, (void **)&pObject); 1132 ok_ole_success(hr, "OleCreate"); 1133 IOleObject_Release(pObject); 1134 CHECK_NO_EXTRA_METHODS(); 1135 1136 expected_method_list = methods_olerender_draw; 1137 trace("OleCreate with OLERENDER_DRAW:\n"); 1138 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject); 1139 ok_ole_success(hr, "OleCreate"); 1140 IOleObject_Release(pObject); 1141 CHECK_NO_EXTRA_METHODS(); 1142 1143 expected_method_list = methods_olerender_draw_with_site; 1144 trace("OleCreate with OLERENDER_DRAW, with site:\n"); 1145 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject); 1146 ok_ole_success(hr, "OleCreate"); 1147 IOleObject_Release(pObject); 1148 CHECK_NO_EXTRA_METHODS(); 1149 1150 /* GetMiscStatus fails */ 1151 g_GetMiscStatusFailsWith = 0x8fafefaf; 1152 expected_method_list = methods_olerender_draw_with_site; 1153 trace("OleCreate with OLERENDER_DRAW, with site:\n"); 1154 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, (IOleClientSite*)0xdeadbeef, pStorage, (void **)&pObject); 1155 ok_ole_success(hr, "OleCreate"); 1156 IOleObject_Release(pObject); 1157 CHECK_NO_EXTRA_METHODS(); 1158 g_GetMiscStatusFailsWith = S_OK; 1159 1160 formatetc.cfFormat = CF_TEXT; 1161 formatetc.ptd = NULL; 1162 formatetc.dwAspect = DVASPECT_CONTENT; 1163 formatetc.lindex = -1; 1164 formatetc.tymed = TYMED_HGLOBAL; 1165 expected_method_list = methods_olerender_format; 1166 trace("OleCreate with OLERENDER_FORMAT:\n"); 1167 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_FORMAT, &formatetc, (IOleClientSite *)0xdeadbeef, pStorage, (void **)&pObject); 1168 ok(hr == S_OK || 1169 broken(hr == E_INVALIDARG), /* win2k */ 1170 "OleCreate failed with error 0x%08x\n", hr); 1171 if (pObject) 1172 { 1173 IOleObject_Release(pObject); 1174 CHECK_NO_EXTRA_METHODS(); 1175 } 1176 1177 expected_method_list = methods_olerender_asis; 1178 trace("OleCreate with OLERENDER_ASIS:\n"); 1179 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_ASIS, NULL, NULL, pStorage, (void **)&pObject); 1180 ok_ole_success(hr, "OleCreate"); 1181 IOleObject_Release(pObject); 1182 CHECK_NO_EXTRA_METHODS(); 1183 1184 formatetc.cfFormat = 0; 1185 formatetc.tymed = TYMED_NULL; 1186 runnable = NULL; 1187 expected_method_list = methods_olerender_draw_no_runnable; 1188 trace("OleCreate with OLERENDER_DRAW (no IRunnableObject):\n"); 1189 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject); 1190 ok_ole_success(hr, "OleCreate"); 1191 IOleObject_Release(pObject); 1192 CHECK_NO_EXTRA_METHODS(); 1193 1194 runnable = &OleObjectRunnable; 1195 cache = NULL; 1196 expected_method_list = methods_olerender_draw_no_cache; 1197 trace("OleCreate with OLERENDER_DRAW (no IOleCache):\n"); 1198 hr = OleCreate(&CLSID_Equation3, &IID_IOleObject, OLERENDER_DRAW, NULL, NULL, pStorage, (void **)&pObject); 1199 ok_ole_success(hr, "OleCreate"); 1200 IOleObject_Release(pObject); 1201 CHECK_NO_EXTRA_METHODS(); 1202 trace("end\n"); 1203 g_expected_fetc = NULL; 1204 } 1205 1206 static void test_OleLoad(IStorage *pStorage) 1207 { 1208 HRESULT hr; 1209 IOleObject *pObject; 1210 DWORD fmt; 1211 1212 static const struct expected_method methods_oleload[] = 1213 { 1214 { "OleObject_QueryInterface", 0 }, 1215 { "OleObject_AddRef", 0 }, 1216 { "OleObject_QueryInterface", 0 }, 1217 { "OleObject_AddRef", 0 }, 1218 { "OleObject_GetMiscStatus", 0 }, 1219 { "OleObject_QueryInterface", 0 }, 1220 { "OleObjectPersistStg_AddRef", 0 }, 1221 { "OleObjectPersistStg_Load", 0 }, 1222 { "OleObjectPersistStg_Release", 0 }, 1223 { "OleObject_SetClientSite", 0 }, 1224 { "OleObject_Release", 0 }, 1225 { "OleObject_QueryInterface", 0 }, 1226 { "OleObject_GetMiscStatus", 0 }, 1227 { "OleObject_Release", 0 }, 1228 { NULL, 0 } 1229 }; 1230 1231 /* Test once with IOleObject_GetMiscStatus failing */ 1232 expected_method_list = methods_oleload; 1233 g_GetMiscStatusFailsWith = E_FAIL; 1234 trace("OleLoad:\n"); 1235 hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject); 1236 ok(hr == S_OK || 1237 broken(hr == E_INVALIDARG), /* win98 and win2k */ 1238 "OleLoad failed with error 0x%08x\n", hr); 1239 if(pObject) 1240 { 1241 DWORD dwStatus = 0xdeadbeef; 1242 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus); 1243 ok(hr == E_FAIL, "Got 0x%08x\n", hr); 1244 ok(dwStatus == 0x1234, "Got 0x%08x\n", dwStatus); 1245 1246 IOleObject_Release(pObject); 1247 CHECK_NO_EXTRA_METHODS(); 1248 } 1249 g_GetMiscStatusFailsWith = S_OK; 1250 1251 /* Test again, let IOleObject_GetMiscStatus succeed. */ 1252 expected_method_list = methods_oleload; 1253 trace("OleLoad:\n"); 1254 hr = OleLoad(pStorage, &IID_IOleObject, (IOleClientSite *)0xdeadbeef, (void **)&pObject); 1255 ok(hr == S_OK || 1256 broken(hr == E_INVALIDARG), /* win98 and win2k */ 1257 "OleLoad failed with error 0x%08x\n", hr); 1258 if (pObject) 1259 { 1260 DWORD dwStatus = 0xdeadbeef; 1261 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus); 1262 ok(hr == S_OK, "Got 0x%08x\n", hr); 1263 ok(dwStatus == 1, "Got 0x%08x\n", dwStatus); 1264 1265 IOleObject_Release(pObject); 1266 CHECK_NO_EXTRA_METHODS(); 1267 } 1268 1269 for (fmt = CF_TEXT; fmt < CF_MAX; fmt++) 1270 { 1271 static const WCHAR olrepres[] = { 2,'O','l','e','P','r','e','s','0','0','0',0 }; 1272 IStorage *stg; 1273 IStream *stream; 1274 IUnknown *obj; 1275 DWORD data, i, data_size; 1276 PresentationDataHeader header; 1277 HDC hdc; 1278 HGDIOBJ hobj; 1279 RECT rc; 1280 char buf[256]; 1281 1282 for (i = 0; i < 7; i++) 1283 { 1284 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &stg); 1285 ok(hr == S_OK, "StgCreateDocfile error %#x\n", hr); 1286 1287 hr = IStorage_SetClass(stg, &CLSID_WineTest); 1288 ok(hr == S_OK, "SetClass error %#x\n", hr); 1289 1290 hr = IStorage_CreateStream(stg, olrepres, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stream); 1291 ok(hr == S_OK, "CreateStream error %#x\n", hr); 1292 1293 data = ~0; 1294 hr = IStream_Write(stream, &data, sizeof(data), NULL); 1295 ok(hr == S_OK, "Write error %#x\n", hr); 1296 1297 data = fmt; 1298 hr = IStream_Write(stream, &data, sizeof(data), NULL); 1299 ok(hr == S_OK, "Write error %#x\n", hr); 1300 1301 switch (fmt) 1302 { 1303 case CF_BITMAP: 1304 /* FIXME: figure out stream format */ 1305 hobj = CreateBitmap(1, 1, 1, 1, NULL); 1306 data_size = GetBitmapBits(hobj, sizeof(buf), buf); 1307 DeleteObject(hobj); 1308 break; 1309 1310 case CF_METAFILEPICT: 1311 case CF_ENHMETAFILE: 1312 hdc = CreateMetaFileA(NULL); 1313 hobj = CloseMetaFile(hdc); 1314 data_size = GetMetaFileBitsEx(hobj, sizeof(buf), buf); 1315 DeleteMetaFile(hobj); 1316 break; 1317 1318 default: 1319 data_size = sizeof(buf); 1320 memset(buf, 'A', sizeof(buf)); 1321 break; 1322 } 1323 1324 header.tdSize = sizeof(header.tdSize); 1325 header.dvAspect = DVASPECT_CONTENT; 1326 header.lindex = -1; 1327 header.advf = 1 << i; 1328 header.unknown7 = 0; 1329 header.dwObjectExtentX = 1; 1330 header.dwObjectExtentY = 1; 1331 header.dwSize = data_size; 1332 hr = IStream_Write(stream, &header, sizeof(header), NULL); 1333 ok(hr == S_OK, "Write error %#x\n", hr); 1334 1335 hr = IStream_Write(stream, buf, data_size, NULL); 1336 ok(hr == S_OK, "Write error %#x\n", hr); 1337 1338 IStream_Release(stream); 1339 1340 hr = OleLoad(stg, &IID_IUnknown, NULL, (void **)&obj); 1341 /* FIXME: figure out stream format */ 1342 if (fmt == CF_BITMAP && hr != S_OK) 1343 { 1344 IStorage_Release(stg); 1345 continue; 1346 } 1347 ok(hr == S_OK, "OleLoad error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf); 1348 1349 hdc = CreateCompatibleDC(0); 1350 SetRect(&rc, 0, 0, 100, 100); 1351 hr = OleDraw(obj, DVASPECT_CONTENT, hdc, &rc); 1352 DeleteDC(hdc); 1353 if (fmt == CF_METAFILEPICT) 1354 ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf); 1355 else if (fmt == CF_ENHMETAFILE) 1356 todo_wine 1357 ok(hr == S_OK, "OleDraw error %#x: cfFormat = %u, advf = %#x\n", hr, fmt, header.advf); 1358 else 1359 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); 1360 1361 IUnknown_Release(obj); 1362 IStorage_Release(stg); 1363 } 1364 } 1365 } 1366 1367 static BOOL STDMETHODCALLTYPE draw_continue(ULONG_PTR param) 1368 { 1369 CHECK_EXPECTED_METHOD("draw_continue"); 1370 return TRUE; 1371 } 1372 1373 static BOOL STDMETHODCALLTYPE draw_continue_false(ULONG_PTR param) 1374 { 1375 CHECK_EXPECTED_METHOD("draw_continue_false"); 1376 return FALSE; 1377 } 1378 1379 static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface, REFIID riid, void **ppv) 1380 { 1381 if (IsEqualIID(riid, &IID_IAdviseSink) || IsEqualIID(riid, &IID_IUnknown)) 1382 { 1383 *ppv = iface; 1384 IAdviseSink_AddRef(iface); 1385 return S_OK; 1386 } 1387 *ppv = NULL; 1388 return E_NOINTERFACE; 1389 } 1390 1391 static ULONG WINAPI AdviseSink_AddRef(IAdviseSink *iface) 1392 { 1393 return 2; 1394 } 1395 1396 static ULONG WINAPI AdviseSink_Release(IAdviseSink *iface) 1397 { 1398 return 1; 1399 } 1400 1401 1402 static void WINAPI AdviseSink_OnDataChange( 1403 IAdviseSink *iface, 1404 FORMATETC *pFormatetc, 1405 STGMEDIUM *pStgmed) 1406 { 1407 CHECK_EXPECTED_METHOD("AdviseSink_OnDataChange"); 1408 } 1409 1410 static void WINAPI AdviseSink_OnViewChange( 1411 IAdviseSink *iface, 1412 DWORD dwAspect, 1413 LONG lindex) 1414 { 1415 CHECK_EXPECTED_METHOD("AdviseSink_OnViewChange"); 1416 } 1417 1418 static void WINAPI AdviseSink_OnRename( 1419 IAdviseSink *iface, 1420 IMoniker *pmk) 1421 { 1422 CHECK_EXPECTED_METHOD("AdviseSink_OnRename"); 1423 } 1424 1425 static void WINAPI AdviseSink_OnSave(IAdviseSink *iface) 1426 { 1427 CHECK_EXPECTED_METHOD("AdviseSink_OnSave"); 1428 } 1429 1430 static void WINAPI AdviseSink_OnClose(IAdviseSink *iface) 1431 { 1432 CHECK_EXPECTED_METHOD("AdviseSink_OnClose"); 1433 } 1434 1435 static const IAdviseSinkVtbl AdviseSinkVtbl = 1436 { 1437 AdviseSink_QueryInterface, 1438 AdviseSink_AddRef, 1439 AdviseSink_Release, 1440 AdviseSink_OnDataChange, 1441 AdviseSink_OnViewChange, 1442 AdviseSink_OnRename, 1443 AdviseSink_OnSave, 1444 AdviseSink_OnClose 1445 }; 1446 1447 static IAdviseSink AdviseSink = { &AdviseSinkVtbl }; 1448 1449 static HRESULT WINAPI DataObject_QueryInterface( 1450 IDataObject* iface, 1451 REFIID riid, 1452 void** ppvObject) 1453 { 1454 CHECK_EXPECTED_METHOD("DataObject_QueryInterface"); 1455 1456 if (IsEqualIID(riid, &IID_IDataObject) || IsEqualIID(riid, &IID_IUnknown)) 1457 { 1458 *ppvObject = iface; 1459 return S_OK; 1460 } 1461 *ppvObject = NULL; 1462 return S_OK; 1463 } 1464 1465 static ULONG WINAPI DataObject_AddRef( 1466 IDataObject* iface) 1467 { 1468 CHECK_EXPECTED_METHOD("DataObject_AddRef"); 1469 return 2; 1470 } 1471 1472 static ULONG WINAPI DataObject_Release( 1473 IDataObject* iface) 1474 { 1475 CHECK_EXPECTED_METHOD("DataObject_Release"); 1476 return 1; 1477 } 1478 1479 static inline BOOL fmtetc_equal( const FORMATETC *a, const FORMATETC *b ) 1480 { 1481 /* FIXME ptd */ 1482 return a->cfFormat == b->cfFormat && a->dwAspect == b->dwAspect && 1483 a->lindex == b->lindex && a->tymed == b->tymed; 1484 1485 } 1486 1487 static HRESULT WINAPI DataObject_GetData( IDataObject *iface, FORMATETC *fmt_in, 1488 STGMEDIUM *med ) 1489 { 1490 FORMATETC *fmt; 1491 1492 CHECK_EXPECTED_METHOD_FMT("DataObject_GetData", fmt_in); 1493 1494 for (fmt = g_dataobject_fmts; fmt && fmt->cfFormat != 0; fmt++) 1495 { 1496 if (fmtetc_equal( fmt_in, fmt )) 1497 { 1498 switch (fmt->cfFormat) 1499 { 1500 case CF_DIB: 1501 create_dib( med ); 1502 return S_OK; 1503 case CF_BITMAP: 1504 create_bitmap( med ); 1505 return S_OK; 1506 case CF_ENHMETAFILE: 1507 create_emf( med ); 1508 return S_OK; 1509 case CF_TEXT: 1510 create_text( med ); 1511 return S_OK; 1512 default: 1513 trace( "unhandled fmt %d\n", fmt->cfFormat ); 1514 } 1515 } 1516 } 1517 1518 return S_FALSE; 1519 } 1520 1521 static HRESULT WINAPI DataObject_GetDataHere( 1522 IDataObject* iface, 1523 LPFORMATETC pformatetc, 1524 STGMEDIUM* pmedium) 1525 { 1526 CHECK_EXPECTED_METHOD("DataObject_GetDataHere"); 1527 return E_NOTIMPL; 1528 } 1529 1530 static HRESULT WINAPI DataObject_QueryGetData( IDataObject *iface, FORMATETC *fmt_in ) 1531 { 1532 FORMATETC *fmt; 1533 1534 CHECK_EXPECTED_METHOD_FMT("DataObject_QueryGetData", fmt_in); 1535 1536 for (fmt = g_dataobject_fmts; fmt && fmt->cfFormat != 0; fmt++) 1537 if (fmtetc_equal( fmt_in, fmt )) return S_OK; 1538 1539 return S_FALSE; 1540 } 1541 1542 static HRESULT WINAPI DataObject_GetCanonicalFormatEtc( 1543 IDataObject* iface, 1544 LPFORMATETC pformatectIn, 1545 LPFORMATETC pformatetcOut) 1546 { 1547 CHECK_EXPECTED_METHOD("DataObject_GetCanonicalFormatEtc"); 1548 return E_NOTIMPL; 1549 } 1550 1551 static HRESULT WINAPI DataObject_SetData( 1552 IDataObject* iface, 1553 LPFORMATETC pformatetc, 1554 STGMEDIUM* pmedium, 1555 BOOL fRelease) 1556 { 1557 CHECK_EXPECTED_METHOD("DataObject_SetData"); 1558 return E_NOTIMPL; 1559 } 1560 1561 static HRESULT WINAPI DataObject_EnumFormatEtc( 1562 IDataObject* iface, 1563 DWORD dwDirection, 1564 IEnumFORMATETC** ppenumFormatEtc) 1565 { 1566 CHECK_EXPECTED_METHOD("DataObject_EnumFormatEtc"); 1567 return E_NOTIMPL; 1568 } 1569 1570 static HRESULT WINAPI DataObject_DAdvise( 1571 IDataObject* iface, 1572 FORMATETC* pformatetc, 1573 DWORD advf, 1574 IAdviseSink* pAdvSink, 1575 DWORD* pdwConnection) 1576 { 1577 STGMEDIUM stgmedium; 1578 1579 CHECK_EXPECTED_METHOD("DataObject_DAdvise"); 1580 *pdwConnection = 1; 1581 1582 if(advf & ADVF_PRIMEFIRST) 1583 { 1584 ok(pformatetc->cfFormat == cf_test_2, "got %04x\n", pformatetc->cfFormat); 1585 stgmedium.tymed = TYMED_HGLOBAL; 1586 U(stgmedium).hGlobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, 4); 1587 stgmedium.pUnkForRelease = NULL; 1588 IAdviseSink_OnDataChange(pAdvSink, pformatetc, &stgmedium); 1589 } 1590 1591 return S_OK; 1592 } 1593 1594 static HRESULT WINAPI DataObject_DUnadvise( 1595 IDataObject* iface, 1596 DWORD dwConnection) 1597 { 1598 CHECK_EXPECTED_METHOD("DataObject_DUnadvise"); 1599 return S_OK; 1600 } 1601 1602 static HRESULT WINAPI DataObject_EnumDAdvise( 1603 IDataObject* iface, 1604 IEnumSTATDATA** ppenumAdvise) 1605 { 1606 CHECK_EXPECTED_METHOD("DataObject_EnumDAdvise"); 1607 return OLE_E_ADVISENOTSUPPORTED; 1608 } 1609 1610 static IDataObjectVtbl DataObjectVtbl = 1611 { 1612 DataObject_QueryInterface, 1613 DataObject_AddRef, 1614 DataObject_Release, 1615 DataObject_GetData, 1616 DataObject_GetDataHere, 1617 DataObject_QueryGetData, 1618 DataObject_GetCanonicalFormatEtc, 1619 DataObject_SetData, 1620 DataObject_EnumFormatEtc, 1621 DataObject_DAdvise, 1622 DataObject_DUnadvise, 1623 DataObject_EnumDAdvise 1624 }; 1625 1626 static IDataObject DataObject = { &DataObjectVtbl }; 1627 1628 static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID riid, void **ppv) 1629 { 1630 *ppv = NULL; 1631 if (IsEqualIID(riid, &IID_IUnknown)) *ppv = iface; 1632 if (*ppv) 1633 { 1634 IUnknown_AddRef((IUnknown *)*ppv); 1635 return S_OK; 1636 } 1637 return E_NOINTERFACE; 1638 } 1639 1640 static ULONG WINAPI Unknown_AddRef(IUnknown *iface) 1641 { 1642 return 2; 1643 } 1644 1645 static ULONG WINAPI Unknown_Release(IUnknown *iface) 1646 { 1647 return 1; 1648 } 1649 1650 static const IUnknownVtbl UnknownVtbl = 1651 { 1652 Unknown_QueryInterface, 1653 Unknown_AddRef, 1654 Unknown_Release 1655 }; 1656 1657 static IUnknown unknown = { &UnknownVtbl }; 1658 1659 static void check_enum_cache(IOleCache2 *cache, const STATDATA *expect, int num) 1660 { 1661 IEnumSTATDATA *enum_stat; 1662 STATDATA stat; 1663 HRESULT hr; 1664 1665 hr = IOleCache2_EnumCache( cache, &enum_stat ); 1666 ok( hr == S_OK, "got %08x\n", hr ); 1667 1668 while (IEnumSTATDATA_Next(enum_stat, 1, &stat, NULL) == S_OK) 1669 { 1670 ok( stat.formatetc.cfFormat == expect->formatetc.cfFormat, "got %d expect %d\n", 1671 stat.formatetc.cfFormat, expect->formatetc.cfFormat ); 1672 ok( !stat.formatetc.ptd == !expect->formatetc.ptd, "got %p expect %p\n", 1673 stat.formatetc.ptd, expect->formatetc.ptd ); 1674 ok( stat.formatetc.dwAspect == expect->formatetc.dwAspect, "got %d expect %d\n", 1675 stat.formatetc.dwAspect, expect->formatetc.dwAspect ); 1676 ok( stat.formatetc.lindex == expect->formatetc.lindex, "got %d expect %d\n", 1677 stat.formatetc.lindex, expect->formatetc.lindex ); 1678 ok( stat.formatetc.tymed == expect->formatetc.tymed, "got %d expect %d\n", 1679 stat.formatetc.tymed, expect->formatetc.tymed ); 1680 ok( stat.advf == expect->advf, "got %d expect %d\n", stat.advf, expect->advf ); 1681 ok( stat.pAdvSink == 0, "got %p\n", stat.pAdvSink ); 1682 ok( stat.dwConnection == expect->dwConnection, "got %d expect %d\n", stat.dwConnection, expect->dwConnection ); 1683 num--; 1684 expect++; 1685 } 1686 1687 ok( num == 0, "incorrect number. num %d\n", num ); 1688 1689 IEnumSTATDATA_Release( enum_stat ); 1690 } 1691 1692 static void test_data_cache(void) 1693 { 1694 HRESULT hr; 1695 IOleCache2 *pOleCache; 1696 IOleCache *olecache; 1697 IStorage *pStorage; 1698 IUnknown *unk, *unk2; 1699 IPersistStorage *pPS; 1700 IViewObject *pViewObject; 1701 IOleCacheControl *pOleCacheControl; 1702 IDataObject *pCacheDataObject; 1703 FORMATETC fmtetc; 1704 STGMEDIUM stgmedium; 1705 DWORD dwConnection; 1706 DWORD dwFreeze; 1707 RECTL rcBounds; 1708 HDC hdcMem; 1709 CLSID clsid; 1710 char szSystemDir[MAX_PATH]; 1711 WCHAR wszPath[MAX_PATH]; 1712 static const WCHAR wszShell32[] = {'\\','s','h','e','l','l','3','2','.','d','l','l',0}; 1713 1714 static const struct expected_method methods_cacheinitnew[] = 1715 { 1716 { "AdviseSink_OnViewChange", 0 }, 1717 { "AdviseSink_OnViewChange", 0 }, 1718 { "draw_continue", 1 }, 1719 { "draw_continue_false", 1 }, 1720 { "DataObject_DAdvise", 0 }, 1721 { "DataObject_DAdvise", 0 }, 1722 { "DataObject_DUnadvise", 0 }, 1723 { "DataObject_DUnadvise", 0 }, 1724 { NULL, 0 } 1725 }; 1726 static const struct expected_method methods_cacheload[] = 1727 { 1728 { "AdviseSink_OnViewChange", 0 }, 1729 { "draw_continue", 1 }, 1730 { "draw_continue", 1 }, 1731 { "draw_continue", 1 }, 1732 { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_THUMBNAIL, -1, TYMED_HGLOBAL} }, 1733 { "DataObject_GetData", 0, { CF_BITMAP, NULL, DVASPECT_THUMBNAIL, -1, TYMED_GDI} }, 1734 { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_ICON, -1, TYMED_MFPICT} }, 1735 { NULL, 0 } 1736 }; 1737 static const struct expected_method methods_cachethenrun[] = 1738 { 1739 { "DataObject_DAdvise", 0 }, 1740 { "DataObject_DAdvise", 0 }, 1741 { "DataObject_DAdvise", 0 }, 1742 { "DataObject_DAdvise", 0 }, 1743 { "DataObject_DUnadvise", 0 }, 1744 { "DataObject_DUnadvise", 0 }, 1745 { "DataObject_DUnadvise", 0 }, 1746 { "DataObject_DUnadvise", 0 }, 1747 { NULL, 0 } 1748 }; 1749 1750 GetSystemDirectoryA(szSystemDir, ARRAY_SIZE(szSystemDir)); 1751 1752 expected_method_list = methods_cacheinitnew; 1753 1754 fmtetc.cfFormat = CF_METAFILEPICT; 1755 fmtetc.dwAspect = DVASPECT_ICON; 1756 fmtetc.lindex = -1; 1757 fmtetc.ptd = NULL; 1758 fmtetc.tymed = TYMED_MFPICT; 1759 1760 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage); 1761 ok_ole_success(hr, "StgCreateDocfile"); 1762 1763 /* aggregation */ 1764 1765 /* requested is not IUnknown */ 1766 hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IOleCache2, (void**)&pOleCache); 1767 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 1768 1769 hr = CreateDataCache(&unknown, &CLSID_NULL, &IID_IUnknown, (void**)&unk); 1770 ok(hr == S_OK, "got 0x%08x\n", hr); 1771 1772 hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache); 1773 ok(hr == S_OK, "got 0x%08x\n", hr); 1774 hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache); 1775 ok(hr == S_OK, "got 0x%08x\n", hr); 1776 ok(unk != (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk); 1777 ok(unk != (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk); 1778 IOleCache2_Release(pOleCache); 1779 IOleCache_Release(olecache); 1780 IUnknown_Release(unk); 1781 1782 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IUnknown, (void**)&unk); 1783 ok(hr == S_OK, "got 0x%08x\n", hr); 1784 hr = IUnknown_QueryInterface(unk, &IID_IOleCache, (void**)&olecache); 1785 ok(hr == S_OK, "got 0x%08x\n", hr); 1786 hr = IUnknown_QueryInterface(unk, &IID_IOleCache2, (void**)&pOleCache); 1787 ok(hr == S_OK, "got 0x%08x\n", hr); 1788 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void**)&unk2); 1789 ok(hr == S_OK, "got 0x%08x\n", hr); 1790 ok(unk == (IUnknown*)olecache, "got %p, expected %p\n", olecache, unk); 1791 ok(unk == (IUnknown*)pOleCache, "got %p, expected %p\n", pOleCache, unk); 1792 ok(unk == unk2, "got %p, expected %p\n", unk2, unk); 1793 IUnknown_Release(unk2); 1794 IOleCache2_Release(pOleCache); 1795 IOleCache_Release(olecache); 1796 IUnknown_Release(unk); 1797 1798 /* Test with new data */ 1799 1800 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache); 1801 ok_ole_success(hr, "CreateDataCache"); 1802 1803 hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS); 1804 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)"); 1805 hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject); 1806 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)"); 1807 hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl); 1808 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)"); 1809 1810 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink); 1811 ok_ole_success(hr, "IViewObject_SetAdvise"); 1812 1813 hr = IPersistStorage_InitNew(pPS, pStorage); 1814 ok_ole_success(hr, "IPersistStorage_InitNew"); 1815 1816 hr = IPersistStorage_IsDirty(pPS); 1817 ok_ole_success(hr, "IPersistStorage_IsDirty"); 1818 1819 hr = IPersistStorage_GetClassID(pPS, &clsid); 1820 ok_ole_success(hr, "IPersistStorage_GetClassID"); 1821 ok(IsEqualCLSID(&clsid, &IID_NULL), "clsid should be blank\n"); 1822 1823 hr = IOleCache2_Uncache(pOleCache, 0xdeadbeef); 1824 ok(hr == OLE_E_NOCONNECTION, "IOleCache_Uncache with invalid value should return OLE_E_NOCONNECTION instead of 0x%x\n", hr); 1825 1826 /* Both tests crash on NT4 and below. StgCreatePropSetStg is only available on w2k and above. */ 1827 if (GetProcAddress(GetModuleHandleA("ole32.dll"), "StgCreatePropSetStg")) 1828 { 1829 hr = IOleCache2_Cache(pOleCache, NULL, 0, &dwConnection); 1830 ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL fmtetc should have returned E_INVALIDARG instead of 0x%08x\n", hr); 1831 1832 hr = IOleCache2_Cache(pOleCache, NULL, 0, NULL); 1833 ok(hr == E_INVALIDARG, "IOleCache_Cache with NULL pdwConnection should have returned E_INVALIDARG instead of 0x%08x\n", hr); 1834 } 1835 else 1836 { 1837 skip("tests with NULL parameters will crash on NT4 and below\n"); 1838 } 1839 1840 for (fmtetc.cfFormat = CF_TEXT; fmtetc.cfFormat < CF_MAX; fmtetc.cfFormat++) 1841 { 1842 int i; 1843 fmtetc.dwAspect = DVASPECT_THUMBNAIL; 1844 for (i = 0; i < 7; i++) 1845 { 1846 fmtetc.tymed = 1 << i; 1847 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 1848 if ((fmtetc.cfFormat == CF_METAFILEPICT && fmtetc.tymed == TYMED_MFPICT) || 1849 (fmtetc.cfFormat == CF_BITMAP && fmtetc.tymed == TYMED_GDI) || 1850 (fmtetc.cfFormat == CF_DIB && fmtetc.tymed == TYMED_HGLOBAL) || 1851 (fmtetc.cfFormat == CF_ENHMETAFILE && fmtetc.tymed == TYMED_ENHMF)) 1852 ok(hr == S_OK, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned S_OK instead of 0x%08x\n", 1853 fmtetc.cfFormat, fmtetc.tymed, hr); 1854 else if (fmtetc.tymed == TYMED_HGLOBAL) 1855 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED || 1856 broken(hr == S_OK && fmtetc.cfFormat == CF_BITMAP) /* Win9x & NT4 */, 1857 "IOleCache_Cache cfFormat = %d, tymed = %d should have returned CACHE_S_FORMATETC_NOTSUPPORTED instead of 0x%08x\n", 1858 fmtetc.cfFormat, fmtetc.tymed, hr); 1859 else 1860 ok(hr == DV_E_TYMED, "IOleCache_Cache cfFormat = %d, tymed = %d should have returned DV_E_TYMED instead of 0x%08x\n", 1861 fmtetc.cfFormat, fmtetc.tymed, hr); 1862 if (SUCCEEDED(hr)) 1863 { 1864 hr = IOleCache2_Uncache(pOleCache, dwConnection); 1865 ok_ole_success(hr, "IOleCache_Uncache"); 1866 } 1867 } 1868 } 1869 1870 fmtetc.cfFormat = CF_BITMAP; 1871 fmtetc.dwAspect = DVASPECT_THUMBNAIL; 1872 fmtetc.tymed = TYMED_GDI; 1873 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 1874 ok_ole_success(hr, "IOleCache_Cache"); 1875 1876 fmtetc.cfFormat = 0; 1877 fmtetc.dwAspect = DVASPECT_ICON; 1878 fmtetc.tymed = TYMED_MFPICT; 1879 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 1880 ok_ole_success(hr, "IOleCache_Cache"); 1881 1882 MultiByteToWideChar(CP_ACP, 0, szSystemDir, -1, wszPath, ARRAY_SIZE(wszPath)); 1883 memcpy(wszPath+lstrlenW(wszPath), wszShell32, sizeof(wszShell32)); 1884 1885 fmtetc.cfFormat = CF_METAFILEPICT; 1886 stgmedium.tymed = TYMED_MFPICT; 1887 U(stgmedium).hMetaFilePict = OleMetafilePictFromIconAndLabel( 1888 LoadIconA(NULL, (LPSTR)IDI_APPLICATION), wszPath, wszPath, 0); 1889 stgmedium.pUnkForRelease = NULL; 1890 1891 fmtetc.dwAspect = DVASPECT_CONTENT; 1892 hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE); 1893 ok(hr == OLE_E_BLANK, "IOleCache_SetData for aspect not in cache should have return OLE_E_BLANK instead of 0x%08x\n", hr); 1894 1895 fmtetc.dwAspect = DVASPECT_ICON; 1896 hr = IOleCache2_SetData(pOleCache, &fmtetc, &stgmedium, FALSE); 1897 ok_ole_success(hr, "IOleCache_SetData"); 1898 ReleaseStgMedium(&stgmedium); 1899 1900 hr = IViewObject_Freeze(pViewObject, DVASPECT_ICON, -1, NULL, &dwFreeze); 1901 todo_wine { 1902 ok_ole_success(hr, "IViewObject_Freeze"); 1903 hr = IViewObject_Freeze(pViewObject, DVASPECT_CONTENT, -1, NULL, &dwFreeze); 1904 ok(hr == OLE_E_BLANK, "IViewObject_Freeze with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr); 1905 } 1906 1907 rcBounds.left = 0; 1908 rcBounds.top = 0; 1909 rcBounds.right = 100; 1910 rcBounds.bottom = 100; 1911 hdcMem = CreateCompatibleDC(NULL); 1912 1913 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 1914 ok_ole_success(hr, "IViewObject_Draw"); 1915 1916 hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 1917 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr); 1918 1919 /* a NULL draw_continue fn ptr */ 1920 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, NULL, 0xdeadbeef); 1921 ok_ole_success(hr, "IViewObject_Draw"); 1922 1923 /* draw_continue that returns FALSE to abort drawing */ 1924 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue_false, 0xdeadbeef); 1925 ok(hr == E_ABORT || 1926 broken(hr == S_OK), /* win9x may skip the callbacks */ 1927 "IViewObject_Draw with draw_continue_false returns 0x%08x\n", hr); 1928 1929 DeleteDC(hdcMem); 1930 1931 hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject); 1932 ok_ole_success(hr, "IOleCacheControl_OnRun"); 1933 1934 hr = IPersistStorage_Save(pPS, pStorage, TRUE); 1935 ok_ole_success(hr, "IPersistStorage_Save"); 1936 1937 hr = IPersistStorage_SaveCompleted(pPS, NULL); 1938 ok_ole_success(hr, "IPersistStorage_SaveCompleted"); 1939 1940 hr = IPersistStorage_IsDirty(pPS); 1941 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr); 1942 1943 IPersistStorage_Release(pPS); 1944 IViewObject_Release(pViewObject); 1945 IOleCache2_Release(pOleCache); 1946 IOleCacheControl_Release(pOleCacheControl); 1947 1948 CHECK_NO_EXTRA_METHODS(); 1949 1950 /* Test with loaded data */ 1951 trace("Testing loaded data with CreateDataCache:\n"); 1952 expected_method_list = methods_cacheload; 1953 1954 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache); 1955 ok_ole_success(hr, "CreateDataCache"); 1956 1957 hr = IOleCache2_QueryInterface(pOleCache, &IID_IPersistStorage, (LPVOID *)&pPS); 1958 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IPersistStorage)"); 1959 hr = IOleCache2_QueryInterface(pOleCache, &IID_IViewObject, (LPVOID *)&pViewObject); 1960 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IViewObject)"); 1961 1962 hr = IViewObject_SetAdvise(pViewObject, DVASPECT_ICON, ADVF_PRIMEFIRST, &AdviseSink); 1963 ok_ole_success(hr, "IViewObject_SetAdvise"); 1964 1965 hr = IPersistStorage_Load(pPS, pStorage); 1966 ok_ole_success(hr, "IPersistStorage_Load"); 1967 1968 hr = IPersistStorage_IsDirty(pPS); 1969 ok(hr == S_FALSE, "IPersistStorage_IsDirty should have returned S_FALSE instead of 0x%x\n", hr); 1970 1971 fmtetc.cfFormat = 0; 1972 fmtetc.dwAspect = DVASPECT_ICON; 1973 fmtetc.lindex = -1; 1974 fmtetc.ptd = NULL; 1975 fmtetc.tymed = TYMED_MFPICT; 1976 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 1977 ok(hr == CACHE_S_SAMECACHE, "IOleCache_Cache with already loaded data format type should return CACHE_S_SAMECACHE instead of 0x%x\n", hr); 1978 1979 rcBounds.left = 0; 1980 rcBounds.top = 0; 1981 rcBounds.right = 100; 1982 rcBounds.bottom = 100; 1983 hdcMem = CreateCompatibleDC(NULL); 1984 1985 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 1986 ok_ole_success(hr, "IViewObject_Draw"); 1987 1988 hr = IViewObject_Draw(pViewObject, DVASPECT_CONTENT, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 1989 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr); 1990 1991 /* unload the cached storage object, causing it to be reloaded */ 1992 hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE); 1993 ok_ole_success(hr, "IOleCache2_DiscardCache"); 1994 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 1995 ok_ole_success(hr, "IViewObject_Draw"); 1996 1997 /* unload the cached storage object, but don't allow it to be reloaded */ 1998 hr = IPersistStorage_HandsOffStorage(pPS); 1999 ok_ole_success(hr, "IPersistStorage_HandsOffStorage"); 2000 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 2001 ok_ole_success(hr, "IViewObject_Draw"); 2002 hr = IOleCache2_DiscardCache(pOleCache, DISCARDCACHE_NOSAVE); 2003 ok_ole_success(hr, "IOleCache2_DiscardCache"); 2004 hr = IViewObject_Draw(pViewObject, DVASPECT_ICON, -1, NULL, NULL, NULL, hdcMem, &rcBounds, NULL, draw_continue, 0xdeadbeef); 2005 ok(hr == OLE_E_BLANK, "IViewObject_Draw with uncached aspect should have returned OLE_E_BLANK instead of 0x%08x\n", hr); 2006 2007 DeleteDC(hdcMem); 2008 2009 hr = IOleCache2_InitCache(pOleCache, &DataObject); 2010 ok(hr == CACHE_E_NOCACHE_UPDATED, "IOleCache_InitCache should have returned CACHE_E_NOCACHE_UPDATED instead of 0x%08x\n", hr); 2011 2012 IPersistStorage_Release(pPS); 2013 IViewObject_Release(pViewObject); 2014 IOleCache2_Release(pOleCache); 2015 2016 CHECK_NO_EXTRA_METHODS(); 2017 2018 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IOleCache2, (LPVOID *)&pOleCache); 2019 ok_ole_success(hr, "CreateDataCache"); 2020 2021 expected_method_list = methods_cachethenrun; 2022 2023 hr = IOleCache2_QueryInterface(pOleCache, &IID_IDataObject, (LPVOID *)&pCacheDataObject); 2024 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IDataObject)"); 2025 hr = IOleCache2_QueryInterface(pOleCache, &IID_IOleCacheControl, (LPVOID *)&pOleCacheControl); 2026 ok_ole_success(hr, "IOleCache_QueryInterface(IID_IOleCacheControl)"); 2027 2028 fmtetc.cfFormat = CF_METAFILEPICT; 2029 fmtetc.dwAspect = DVASPECT_CONTENT; 2030 fmtetc.tymed = TYMED_MFPICT; 2031 2032 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 2033 ok_ole_success(hr, "IOleCache_Cache"); 2034 2035 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); 2036 ok(hr == OLE_E_BLANK, "got %08x\n", hr); 2037 2038 fmtetc.cfFormat = cf_test_1; 2039 fmtetc.dwAspect = DVASPECT_CONTENT; 2040 fmtetc.tymed = TYMED_HGLOBAL; 2041 2042 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 2043 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr); 2044 2045 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); 2046 ok(hr == OLE_E_BLANK, "got %08x\n", hr); 2047 2048 fmtetc.cfFormat = cf_test_2; 2049 hr = IOleCache2_Cache(pOleCache, &fmtetc, ADVF_PRIMEFIRST, &dwConnection); 2050 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr); 2051 2052 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); 2053 ok(hr == OLE_E_BLANK, "got %08x\n", hr); 2054 2055 hr = IOleCacheControl_OnRun(pOleCacheControl, &DataObject); 2056 ok_ole_success(hr, "IOleCacheControl_OnRun"); 2057 2058 fmtetc.cfFormat = cf_test_3; 2059 hr = IOleCache2_Cache(pOleCache, &fmtetc, 0, &dwConnection); 2060 ok(hr == CACHE_S_FORMATETC_NOTSUPPORTED, "got %08x\n", hr); 2061 2062 fmtetc.cfFormat = cf_test_1; 2063 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); 2064 ok(hr == OLE_E_BLANK, "got %08x\n", hr); 2065 2066 fmtetc.cfFormat = cf_test_2; 2067 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); 2068 ok(hr == S_OK, "got %08x\n", hr); 2069 ReleaseStgMedium(&stgmedium); 2070 2071 fmtetc.cfFormat = cf_test_3; 2072 hr = IDataObject_GetData(pCacheDataObject, &fmtetc, &stgmedium); 2073 ok(hr == OLE_E_BLANK, "got %08x\n", hr); 2074 2075 IOleCacheControl_Release(pOleCacheControl); 2076 IDataObject_Release(pCacheDataObject); 2077 IOleCache2_Release(pOleCache); 2078 2079 CHECK_NO_EXTRA_METHODS(); 2080 2081 IStorage_Release(pStorage); 2082 } 2083 2084 static const WCHAR CONTENTS[] = {'C','O','N','T','E','N','T','S',0}; 2085 2086 /* 2 x 1 x 32 bpp dib. PelsPerMeter = 200x400 */ 2087 static BYTE file_dib[] = 2088 { 2089 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 2090 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, 2091 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 2092 0x00, 0x00, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 2093 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 2094 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 2095 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 2096 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 2097 }; 2098 2099 static IStorage *create_storage( int num ) 2100 { 2101 IStorage *stg; 2102 IStream *stm; 2103 HRESULT hr; 2104 ULONG written; 2105 2106 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg ); 2107 ok( hr == S_OK, "got %08x\n", hr); 2108 hr = IStorage_SetClass( stg, &CLSID_Picture_Dib ); 2109 ok( hr == S_OK, "got %08x\n", hr); 2110 hr = IStorage_CreateStream( stg, CONTENTS, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE, 0, 0, &stm ); 2111 ok( hr == S_OK, "got %08x\n", hr); 2112 if (num == 1) /* Set biXPelsPerMeter = 0 */ 2113 { 2114 file_dib[0x26] = 0; 2115 file_dib[0x27] = 0; 2116 } 2117 hr = IStream_Write( stm, file_dib, sizeof(file_dib), &written ); 2118 ok( hr == S_OK, "got %08x\n", hr); 2119 IStream_Release( stm ); 2120 return stg; 2121 } 2122 2123 static void test_data_cache_dib_contents_stream(int num) 2124 { 2125 HRESULT hr; 2126 IUnknown *unk; 2127 IPersistStorage *persist; 2128 IDataObject *data; 2129 IViewObject2 *view; 2130 IStorage *stg; 2131 IOleCache2 *cache; 2132 FORMATETC fmt = {CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; 2133 STGMEDIUM med; 2134 CLSID cls; 2135 SIZEL sz; 2136 BYTE *ptr; 2137 BITMAPINFOHEADER expect_info; 2138 STATDATA enum_expect[] = 2139 { 2140 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 }, 2141 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 }, 2142 }; 2143 2144 hr = CreateDataCache( NULL, &CLSID_Picture_Metafile, &IID_IUnknown, (void **)&unk ); 2145 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2146 hr = IUnknown_QueryInterface( unk, &IID_IPersistStorage, (void **)&persist ); 2147 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2148 hr = IUnknown_QueryInterface( unk, &IID_IDataObject, (void **)&data ); 2149 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2150 hr = IUnknown_QueryInterface( unk, &IID_IViewObject2, (void **)&view ); 2151 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2152 hr = IUnknown_QueryInterface( unk, &IID_IOleCache2, (void **)&cache ); 2153 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2154 2155 stg = create_storage( num ); 2156 2157 hr = IPersistStorage_Load( persist, stg ); 2158 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2159 IStorage_Release( stg ); 2160 2161 hr = IPersistStorage_GetClassID( persist, &cls ); 2162 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2163 ok( IsEqualCLSID( &cls, &CLSID_Picture_Dib ), "class id mismatch\n" ); 2164 2165 hr = IDataObject_GetData( data, &fmt, &med ); 2166 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2167 ok( med.tymed == TYMED_HGLOBAL, "got %x\n", med.tymed ); 2168 ok( GlobalSize( U(med).hGlobal ) >= sizeof(dib) - sizeof(BITMAPFILEHEADER), 2169 "got %lu\n", GlobalSize( U(med).hGlobal ) ); 2170 ptr = GlobalLock( U(med).hGlobal ); 2171 2172 expect_info = *(BITMAPINFOHEADER *)(file_dib + sizeof(BITMAPFILEHEADER)); 2173 if (expect_info.biXPelsPerMeter == 0 || expect_info.biYPelsPerMeter == 0) 2174 { 2175 HDC hdc = GetDC( 0 ); 2176 expect_info.biXPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSX ), 10000, 254 ); 2177 expect_info.biYPelsPerMeter = MulDiv( GetDeviceCaps( hdc, LOGPIXELSY ), 10000, 254 ); 2178 ReleaseDC( 0, hdc ); 2179 } 2180 ok( !memcmp( ptr, &expect_info, sizeof(expect_info) ), "mismatch\n" ); 2181 ok( !memcmp( ptr + sizeof(expect_info), file_dib + sizeof(BITMAPFILEHEADER) + sizeof(expect_info), 2182 sizeof(file_dib) - sizeof(BITMAPFILEHEADER) - sizeof(expect_info) ), "mismatch\n" ); 2183 GlobalUnlock( U(med).hGlobal ); 2184 ReleaseStgMedium( &med ); 2185 2186 check_enum_cache( cache, enum_expect, 2 ); 2187 2188 hr = IViewObject2_GetExtent( view, DVASPECT_CONTENT, -1, NULL, &sz ); 2189 ok( SUCCEEDED(hr), "got %08x\n", hr ); 2190 if (num == 0) 2191 { 2192 ok( sz.cx == 1000, "got %d\n", sz.cx ); 2193 ok( sz.cy == 250, "got %d\n", sz.cy ); 2194 } 2195 else 2196 { 2197 HDC hdc = GetDC( 0 ); 2198 LONG x = 2 * 2540 / GetDeviceCaps( hdc, LOGPIXELSX ); 2199 LONG y = 1 * 2540 / GetDeviceCaps( hdc, LOGPIXELSY ); 2200 ok( sz.cx == x, "got %d %d\n", sz.cx, x ); 2201 ok( sz.cy == y, "got %d %d\n", sz.cy, y ); 2202 2203 ReleaseDC( 0, hdc ); 2204 } 2205 2206 IOleCache2_Release( cache ); 2207 IViewObject2_Release( view ); 2208 IDataObject_Release( data ); 2209 IPersistStorage_Release( persist ); 2210 IUnknown_Release( unk ); 2211 } 2212 2213 static void check_bitmap_size( HBITMAP h, int cx, int cy ) 2214 { 2215 BITMAP bm; 2216 2217 GetObjectW( h, sizeof(bm), &bm ); 2218 ok( bm.bmWidth == cx, "got %d expect %d\n", bm.bmWidth, cx ); 2219 ok( bm.bmHeight == cy, "got %d expect %d\n", bm.bmHeight, cy ); 2220 } 2221 2222 static void check_dib_size( HGLOBAL h, int cx, int cy ) 2223 { 2224 BITMAPINFO *info; 2225 2226 info = GlobalLock( h ); 2227 ok( info->bmiHeader.biWidth == cx, "got %d expect %d\n", info->bmiHeader.biWidth, cx ); 2228 ok( info->bmiHeader.biHeight == cy, "got %d expect %d\n", info->bmiHeader.biHeight, cy ); 2229 GlobalUnlock( h ); 2230 } 2231 2232 static void test_data_cache_cache(void) 2233 { 2234 HRESULT hr; 2235 IOleCache2 *cache; 2236 IDataObject *data; 2237 FORMATETC fmt; 2238 DWORD conn; 2239 STGMEDIUM med; 2240 STATDATA expect[] = 2241 { 2242 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 }, 2243 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 0 }, 2244 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 0 }, 2245 {{ CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 0 } 2246 }; 2247 STATDATA view_caching[] = 2248 { 2249 {{ 0, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 0 }, 2250 {{ 0, 0, DVASPECT_THUMBNAIL, -1, TYMED_HGLOBAL }, 0, NULL, 0 }, 2251 {{ 0, 0, DVASPECT_DOCPRINT, -1, TYMED_HGLOBAL }, 0, NULL, 0 }, 2252 {{ CF_METAFILEPICT, 0, DVASPECT_ICON, -1, TYMED_MFPICT }, 0, NULL, 0 } 2253 }; 2254 2255 hr = CreateDataCache( NULL, &CLSID_NULL, &IID_IOleCache2, (void **)&cache ); 2256 ok( hr == S_OK, "got %08x\n", hr ); 2257 2258 /* create a dib entry which will also create a bitmap entry too */ 2259 fmt.cfFormat = CF_DIB; 2260 fmt.ptd = NULL; 2261 fmt.dwAspect = DVASPECT_CONTENT; 2262 fmt.lindex = -1; 2263 fmt.tymed = TYMED_HGLOBAL; 2264 2265 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2266 ok( hr == S_OK, "got %08x\n", hr ); 2267 ok( conn == 2, "got %d\n", conn ); 2268 expect[0].dwConnection = conn; 2269 expect[1].dwConnection = conn; 2270 2271 check_enum_cache( cache, expect, 2 ); 2272 2273 /* now try to add a bitmap */ 2274 fmt.cfFormat = CF_BITMAP; 2275 fmt.tymed = TYMED_GDI; 2276 2277 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2278 ok( hr == CACHE_S_SAMECACHE, "got %08x\n", hr ); 2279 2280 /* metafile */ 2281 fmt.cfFormat = CF_METAFILEPICT; 2282 fmt.tymed = TYMED_MFPICT; 2283 2284 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2285 ok( hr == S_OK, "got %08x\n", hr ); 2286 ok( conn == 3, "got %d\n", conn ); 2287 expect[2].dwConnection = conn; 2288 2289 check_enum_cache( cache, expect, 3); 2290 2291 /* enhmetafile */ 2292 fmt.cfFormat = CF_ENHMETAFILE; 2293 fmt.tymed = TYMED_ENHMF; 2294 2295 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2296 ok( hr == S_OK, "got %08x\n", hr ); 2297 ok( conn == 4, "got %d\n", conn ); 2298 expect[3].dwConnection = conn; 2299 2300 check_enum_cache( cache, expect, 4 ); 2301 2302 /* uncache everything */ 2303 hr = IOleCache2_Uncache( cache, expect[3].dwConnection ); 2304 ok( hr == S_OK, "got %08x\n", hr ); 2305 hr = IOleCache2_Uncache( cache, expect[2].dwConnection ); 2306 ok( hr == S_OK, "got %08x\n", hr ); 2307 hr = IOleCache2_Uncache( cache, expect[0].dwConnection ); 2308 ok( hr == S_OK, "got %08x\n", hr ); 2309 hr = IOleCache2_Uncache( cache, expect[0].dwConnection ); 2310 ok( hr == OLE_E_NOCONNECTION, "got %08x\n", hr ); 2311 2312 check_enum_cache( cache, expect, 0 ); 2313 2314 /* just create a bitmap entry which again adds both dib and bitmap */ 2315 fmt.cfFormat = CF_BITMAP; 2316 fmt.tymed = TYMED_GDI; 2317 2318 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2319 ok( hr == S_OK, "got %08x\n", hr ); 2320 2321 expect[0].dwConnection = conn; 2322 expect[1].dwConnection = conn; 2323 2324 check_enum_cache( cache, expect, 2 ); 2325 2326 /* Try setting a 1x1 bitmap */ 2327 hr = IOleCache2_QueryInterface( cache, &IID_IDataObject, (void **) &data ); 2328 ok( hr == S_OK, "got %08x\n", hr ); 2329 2330 create_bitmap( &med ); 2331 2332 hr = IOleCache2_SetData( cache, &fmt, &med, TRUE ); 2333 ok( hr == S_OK, "got %08x\n", hr ); 2334 2335 hr = IDataObject_GetData( data, &fmt, &med ); 2336 ok( hr == S_OK, "got %08x\n", hr ); 2337 ok( med.tymed == TYMED_GDI, "got %d\n", med.tymed ); 2338 check_bitmap_size( U(med).hBitmap, 1, 1 ); 2339 ReleaseStgMedium( &med ); 2340 2341 fmt.cfFormat = CF_DIB; 2342 fmt.tymed = TYMED_HGLOBAL; 2343 hr = IDataObject_GetData( data, &fmt, &med ); 2344 ok( hr == S_OK, "got %08x\n", hr ); 2345 ok( med.tymed == TYMED_HGLOBAL, "got %d\n", med.tymed ); 2346 check_dib_size( U(med).hGlobal, 1, 1 ); 2347 ReleaseStgMedium( &med ); 2348 2349 /* Now set a 2x1 dib */ 2350 fmt.cfFormat = CF_DIB; 2351 fmt.tymed = TYMED_HGLOBAL; 2352 create_dib( &med ); 2353 2354 hr = IOleCache2_SetData( cache, &fmt, &med, TRUE ); 2355 ok( hr == S_OK, "got %08x\n", hr ); 2356 2357 fmt.cfFormat = CF_BITMAP; 2358 fmt.tymed = TYMED_GDI; 2359 hr = IDataObject_GetData( data, &fmt, &med ); 2360 ok( hr == S_OK, "got %08x\n", hr ); 2361 ok( med.tymed == TYMED_GDI, "got %d\n", med.tymed ); 2362 check_bitmap_size( U(med).hBitmap, 2, 1 ); 2363 ReleaseStgMedium( &med ); 2364 2365 fmt.cfFormat = CF_DIB; 2366 fmt.tymed = TYMED_HGLOBAL; 2367 hr = IDataObject_GetData( data, &fmt, &med ); 2368 ok( hr == S_OK, "got %08x\n", hr ); 2369 ok( med.tymed == TYMED_HGLOBAL, "got %d\n", med.tymed ); 2370 check_dib_size( U(med).hGlobal, 2, 1 ); 2371 ReleaseStgMedium( &med ); 2372 2373 /* uncache everything */ 2374 hr = IOleCache2_Uncache( cache, conn ); 2375 ok( hr == S_OK, "got %08x\n", hr ); 2376 2377 /* view caching */ 2378 fmt.cfFormat = 0; 2379 fmt.tymed = TYMED_ENHMF; 2380 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2381 ok( hr == S_OK, "got %08x\n", hr ); 2382 view_caching[0].dwConnection = conn; 2383 2384 fmt.tymed = TYMED_HGLOBAL; 2385 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2386 ok( hr == CACHE_S_SAMECACHE, "got %08x\n", hr ); 2387 2388 fmt.dwAspect = DVASPECT_THUMBNAIL; 2389 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2390 ok( hr == S_OK, "got %08x\n", hr ); 2391 view_caching[1].dwConnection = conn; 2392 2393 fmt.dwAspect = DVASPECT_DOCPRINT; 2394 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2395 ok( hr == S_OK, "got %08x\n", hr ); 2396 view_caching[2].dwConnection = conn; 2397 2398 /* DVASPECT_ICON view cache gets mapped to CF_METAFILEPICT */ 2399 fmt.dwAspect = DVASPECT_ICON; 2400 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2401 ok( hr == S_OK, "got %08x\n", hr ); 2402 view_caching[3].dwConnection = conn; 2403 2404 check_enum_cache( cache, view_caching, 4 ); 2405 2406 /* uncache everything */ 2407 hr = IOleCache2_Uncache( cache, view_caching[3].dwConnection ); 2408 ok( hr == S_OK, "got %08x\n", hr ); 2409 hr = IOleCache2_Uncache( cache, view_caching[2].dwConnection ); 2410 ok( hr == S_OK, "got %08x\n", hr ); 2411 hr = IOleCache2_Uncache( cache, view_caching[1].dwConnection ); 2412 ok( hr == S_OK, "got %08x\n", hr ); 2413 hr = IOleCache2_Uncache( cache, view_caching[0].dwConnection ); 2414 ok( hr == S_OK, "got %08x\n", hr ); 2415 2416 /* Only able to set cfFormat == CF_METAFILEPICT (or == 0, see above) for DVASPECT_ICON */ 2417 fmt.dwAspect = DVASPECT_ICON; 2418 fmt.cfFormat = CF_DIB; 2419 fmt.tymed = TYMED_HGLOBAL; 2420 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2421 ok( hr == DV_E_FORMATETC, "got %08x\n", hr ); 2422 fmt.cfFormat = CF_BITMAP; 2423 fmt.tymed = TYMED_GDI; 2424 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2425 ok( hr == DV_E_FORMATETC, "got %08x\n", hr ); 2426 fmt.cfFormat = CF_ENHMETAFILE; 2427 fmt.tymed = TYMED_ENHMF; 2428 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2429 ok( hr == DV_E_FORMATETC, "got %08x\n", hr ); 2430 fmt.cfFormat = CF_METAFILEPICT; 2431 fmt.tymed = TYMED_MFPICT; 2432 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2433 ok( hr == S_OK, "got %08x\n", hr ); 2434 2435 /* uncache everything */ 2436 hr = IOleCache2_Uncache( cache, conn ); 2437 ok( hr == S_OK, "got %08x\n", hr ); 2438 2439 /* tymed == 0 */ 2440 fmt.cfFormat = CF_ENHMETAFILE; 2441 fmt.dwAspect = DVASPECT_CONTENT; 2442 fmt.tymed = 0; 2443 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2444 ok( hr == DV_E_TYMED, "got %08x\n", hr ); 2445 2446 IDataObject_Release( data ); 2447 IOleCache2_Release( cache ); 2448 2449 /* tests for a static class cache */ 2450 hr = CreateDataCache( NULL, &CLSID_Picture_Dib, &IID_IOleCache2, (void **)&cache ); 2451 2452 fmt.cfFormat = CF_DIB; 2453 fmt.dwAspect = DVASPECT_CONTENT; 2454 fmt.tymed = TYMED_HGLOBAL; 2455 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2456 ok( hr == CACHE_S_SAMECACHE, "got %08x\n", hr ); 2457 2458 /* aspect other than DVASPECT_CONTENT should fail */ 2459 fmt.dwAspect = DVASPECT_THUMBNAIL; 2460 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2461 ok( FAILED(hr), "got %08x\n", hr ); 2462 2463 fmt.dwAspect = DVASPECT_DOCPRINT; 2464 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2465 ok( FAILED(hr), "got %08x\n", hr ); 2466 2467 /* try caching another clip format */ 2468 fmt.cfFormat = CF_METAFILEPICT; 2469 fmt.dwAspect = DVASPECT_CONTENT; 2470 fmt.tymed = TYMED_MFPICT; 2471 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2472 ok( FAILED(hr), "got %08x\n", hr ); 2473 2474 /* As an exception, it's possible to add an icon aspect */ 2475 fmt.cfFormat = CF_METAFILEPICT; 2476 fmt.dwAspect = DVASPECT_ICON; 2477 fmt.tymed = TYMED_MFPICT; 2478 hr = IOleCache2_Cache( cache, &fmt, 0, &conn ); 2479 ok( hr == S_OK, "got %08x\n", hr ); 2480 2481 IOleCache2_Release( cache ); 2482 } 2483 2484 /* The CLSID_Picture_ classes automatically create appropriate cache entries */ 2485 static void test_data_cache_init(void) 2486 { 2487 HRESULT hr; 2488 IOleCache2 *cache; 2489 IPersistStorage *persist; 2490 int i; 2491 CLSID clsid; 2492 static const STATDATA enum_expect[] = 2493 { 2494 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 }, 2495 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 }, 2496 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 1 }, 2497 {{ CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 0, NULL, 1 } 2498 }; 2499 static const struct 2500 { 2501 const CLSID *clsid; 2502 int enum_start, enum_num; 2503 } data[] = 2504 { 2505 { &CLSID_NULL, 0, 0 }, 2506 { &CLSID_WineTestOld, 0, 0 }, 2507 { &CLSID_Picture_Dib, 0, 2 }, 2508 { &CLSID_Picture_Metafile, 2, 1 }, 2509 { &CLSID_Picture_EnhMetafile, 3, 1 } 2510 }; 2511 2512 for (i = 0; i < ARRAY_SIZE(data); i++) 2513 { 2514 hr = CreateDataCache( NULL, data[i].clsid, &IID_IOleCache2, (void **)&cache ); 2515 ok( hr == S_OK, "got %08x\n", hr ); 2516 2517 check_enum_cache( cache, enum_expect + data[i].enum_start , data[i].enum_num ); 2518 2519 IOleCache2_QueryInterface( cache, &IID_IPersistStorage, (void **) &persist ); 2520 hr = IPersistStorage_GetClassID( persist, &clsid ); 2521 ok( hr == S_OK, "got %08x\n", hr ); 2522 ok( IsEqualCLSID( &clsid, data[i].clsid ), "class id mismatch %s %s\n", wine_dbgstr_guid( &clsid ), 2523 wine_dbgstr_guid( data[i].clsid ) ); 2524 2525 IPersistStorage_Release( persist ); 2526 IOleCache2_Release( cache ); 2527 } 2528 } 2529 2530 static void test_data_cache_initnew(void) 2531 { 2532 HRESULT hr; 2533 IOleCache2 *cache; 2534 IPersistStorage *persist; 2535 IStorage *stg_dib, *stg_mf, *stg_wine; 2536 CLSID clsid; 2537 static const STATDATA initnew_expect[] = 2538 { 2539 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 }, 2540 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 }, 2541 }; 2542 static const STATDATA initnew2_expect[] = 2543 { 2544 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 1 }, 2545 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 }, 2546 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 }, 2547 }; 2548 static const STATDATA initnew3_expect[] = 2549 { 2550 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 1 }, 2551 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 1 }, 2552 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 }, 2553 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 }, 2554 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 3 }, 2555 }; 2556 static const STATDATA initnew4_expect[] = 2557 { 2558 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 2 }, 2559 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 2 }, 2560 {{ CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 0, NULL, 3 }, 2561 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 4 }, 2562 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 4 }, 2563 }; 2564 2565 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_dib ); 2566 ok( hr == S_OK, "got %08x\n", hr); 2567 hr = IStorage_SetClass( stg_dib, &CLSID_Picture_Dib ); 2568 ok( hr == S_OK, "got %08x\n", hr); 2569 2570 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_mf ); 2571 ok( hr == S_OK, "got %08x\n", hr); 2572 hr = IStorage_SetClass( stg_mf, &CLSID_Picture_Metafile ); 2573 ok( hr == S_OK, "got %08x\n", hr); 2574 2575 hr = StgCreateDocfile( NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_DELETEONRELEASE, 0, &stg_wine ); 2576 ok( hr == S_OK, "got %08x\n", hr); 2577 hr = IStorage_SetClass( stg_wine, &CLSID_WineTestOld ); 2578 ok( hr == S_OK, "got %08x\n", hr); 2579 2580 hr = CreateDataCache( NULL, &CLSID_WineTestOld, &IID_IOleCache2, (void **)&cache ); 2581 ok( hr == S_OK, "got %08x\n", hr ); 2582 IOleCache2_QueryInterface( cache, &IID_IPersistStorage, (void **) &persist ); 2583 2584 hr = IPersistStorage_InitNew( persist, stg_dib ); 2585 ok( hr == S_OK, "got %08x\n", hr); 2586 2587 hr = IPersistStorage_GetClassID( persist, &clsid ); 2588 ok( hr == S_OK, "got %08x\n", hr ); 2589 ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) ); 2590 2591 check_enum_cache( cache, initnew_expect, 2 ); 2592 2593 hr = IPersistStorage_InitNew( persist, stg_mf ); 2594 ok( hr == CO_E_ALREADYINITIALIZED, "got %08x\n", hr); 2595 2596 hr = IPersistStorage_HandsOffStorage( persist ); 2597 ok( hr == S_OK, "got %08x\n", hr); 2598 2599 hr = IPersistStorage_GetClassID( persist, &clsid ); 2600 ok( hr == S_OK, "got %08x\n", hr ); 2601 ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) ); 2602 2603 hr = IPersistStorage_InitNew( persist, stg_mf ); 2604 ok( hr == S_OK, "got %08x\n", hr); 2605 2606 hr = IPersistStorage_GetClassID( persist, &clsid ); 2607 ok( hr == S_OK, "got %08x\n", hr ); 2608 ok( IsEqualCLSID( &clsid, &CLSID_Picture_Metafile ), "got %s\n", wine_dbgstr_guid( &clsid ) ); 2609 2610 check_enum_cache( cache, initnew2_expect, 3 ); 2611 2612 hr = IPersistStorage_HandsOffStorage( persist ); 2613 ok( hr == S_OK, "got %08x\n", hr); 2614 2615 hr = IPersistStorage_InitNew( persist, stg_dib ); 2616 ok( hr == S_OK, "got %08x\n", hr); 2617 2618 hr = IPersistStorage_GetClassID( persist, &clsid ); 2619 ok( hr == S_OK, "got %08x\n", hr ); 2620 ok( IsEqualCLSID( &clsid, &CLSID_Picture_Dib ), "got %s\n", wine_dbgstr_guid( &clsid ) ); 2621 2622 check_enum_cache( cache, initnew3_expect, 5 ); 2623 2624 hr = IPersistStorage_HandsOffStorage( persist ); 2625 ok( hr == S_OK, "got %08x\n", hr); 2626 2627 hr = IPersistStorage_InitNew( persist, stg_wine ); 2628 ok( hr == S_OK, "got %08x\n", hr); 2629 2630 hr = IPersistStorage_GetClassID( persist, &clsid ); 2631 ok( hr == S_OK, "got %08x\n", hr ); 2632 ok( IsEqualCLSID( &clsid, &CLSID_WineTestOld ), "got %s\n", wine_dbgstr_guid( &clsid ) ); 2633 2634 check_enum_cache( cache, initnew4_expect, 5 ); 2635 2636 IStorage_Release( stg_wine ); 2637 IStorage_Release( stg_mf ); 2638 IStorage_Release( stg_dib ); 2639 2640 IPersistStorage_Release( persist ); 2641 IOleCache2_Release( cache ); 2642 } 2643 2644 static void test_data_cache_updatecache( void ) 2645 { 2646 HRESULT hr; 2647 IOleCache2 *cache; 2648 FORMATETC fmt; 2649 DWORD conn[4]; 2650 2651 static const struct expected_method methods_dib[] = 2652 { 2653 { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, 2654 { "DataObject_GetData", 0, { CF_BITMAP, NULL, DVASPECT_CONTENT, -1, TYMED_GDI } }, 2655 { NULL } 2656 }; 2657 2658 static const struct expected_method methods_dib_emf[] = 2659 { 2660 { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, 2661 { "DataObject_GetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } }, 2662 { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, 2663 { NULL } 2664 }; 2665 static const struct expected_method methods_dib_wmf[] = 2666 { 2667 { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, 2668 { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, 2669 { NULL } 2670 }; 2671 static const struct expected_method methods_viewcache[] = 2672 { 2673 { "DataObject_QueryGetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, 2674 { "DataObject_QueryGetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } }, 2675 { "DataObject_QueryGetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, 2676 { "DataObject_QueryGetData", 0, { CF_BITMAP, NULL, DVASPECT_CONTENT, -1, TYMED_GDI } }, 2677 { NULL } 2678 }; 2679 static const struct expected_method methods_viewcache_with_dib[] = 2680 { 2681 { "DataObject_QueryGetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, 2682 { "DataObject_QueryGetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } }, 2683 { "DataObject_QueryGetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, 2684 { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, 2685 { NULL } 2686 }; 2687 static const struct expected_method methods_flags_all[] = 2688 { 2689 { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, 2690 { "DataObject_GetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } }, 2691 { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, 2692 { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, 2693 { NULL } 2694 }; 2695 static const struct expected_method methods_flags_ifblank_1[] = 2696 { 2697 { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, 2698 { NULL } 2699 }; 2700 static const struct expected_method methods_flags_ifblank_2[] = 2701 { 2702 { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, 2703 { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, 2704 { NULL } 2705 }; 2706 static const struct expected_method methods_flags_normal[] = 2707 { 2708 { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, 2709 { NULL } 2710 }; 2711 static const struct expected_method methods_initcache[] = 2712 { 2713 { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, 2714 { "DataObject_GetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_MFPICT } }, 2715 { NULL } 2716 }; 2717 static const struct expected_method methods_empty[] = 2718 { 2719 { NULL } 2720 }; 2721 2722 static STATDATA view_cache[] = 2723 { 2724 {{ 0, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 } 2725 }; 2726 static STATDATA view_cache_after_dib[] = 2727 { 2728 {{ CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 0, NULL, 0 }, 2729 {{ CF_BITMAP, 0, DVASPECT_CONTENT, -1, TYMED_GDI }, 0, NULL, 0 } 2730 }; 2731 2732 static FORMATETC dib_fmt[] = 2733 { 2734 { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 2735 { 0 } 2736 }; 2737 2738 hr = CreateDataCache( NULL, &CLSID_WineTestOld, &IID_IOleCache2, (void **)&cache ); 2739 ok( hr == S_OK, "got %08x\n", hr ); 2740 2741 /* No cache slots */ 2742 g_dataobject_fmts = NULL; 2743 expected_method_list = NULL; 2744 2745 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); 2746 ok( hr == S_OK, "got %08x\n", hr ); 2747 2748 /* A dib cache slot */ 2749 fmt.cfFormat = CF_DIB; 2750 fmt.ptd = NULL; 2751 fmt.dwAspect = DVASPECT_CONTENT; 2752 fmt.lindex = -1; 2753 fmt.tymed = TYMED_HGLOBAL; 2754 2755 hr = IOleCache2_Cache( cache, &fmt, 0, &conn[0] ); 2756 ok( hr == S_OK, "got %08x\n", hr ); 2757 2758 expected_method_list = methods_dib; 2759 2760 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); 2761 ok( hr == CACHE_E_NOCACHE_UPDATED, "got %08x\n", hr ); 2762 2763 CHECK_NO_EXTRA_METHODS(); 2764 2765 /* Now with a dib available */ 2766 g_dataobject_fmts = dib_fmt; 2767 expected_method_list = methods_dib; 2768 2769 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); 2770 ok( hr == S_OK, "got %08x\n", hr ); 2771 2772 /* Add an EMF cache slot */ 2773 fmt.cfFormat = CF_ENHMETAFILE; 2774 fmt.ptd = NULL; 2775 fmt.dwAspect = DVASPECT_CONTENT; 2776 fmt.lindex = -1; 2777 fmt.tymed = TYMED_ENHMF; 2778 2779 hr = IOleCache2_Cache( cache, &fmt, 0, &conn[1] ); 2780 ok( hr == S_OK, "got %08x\n", hr ); 2781 2782 g_dataobject_fmts = dib_fmt; 2783 expected_method_list = methods_dib_emf; 2784 2785 /* Two slots to fill, only the dib will succeed */ 2786 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); 2787 ok( hr == S_OK, "got %08x\n", hr ); 2788 2789 CHECK_NO_EXTRA_METHODS(); 2790 2791 /* Replace the emf slot with a wmf */ 2792 hr = IOleCache2_Uncache( cache, conn[1] ); 2793 ok( hr == S_OK, "got %08x\n", hr ); 2794 2795 fmt.cfFormat = CF_METAFILEPICT; 2796 fmt.ptd = NULL; 2797 fmt.dwAspect = DVASPECT_CONTENT; 2798 fmt.lindex = -1; 2799 fmt.tymed = TYMED_MFPICT; 2800 2801 hr = IOleCache2_Cache( cache, &fmt, 0, &conn[1] ); 2802 ok( hr == S_OK, "got %08x\n", hr ); 2803 2804 g_dataobject_fmts = dib_fmt; 2805 expected_method_list = methods_dib_wmf; 2806 2807 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); 2808 ok( hr == S_OK, "got %08x\n", hr ); 2809 2810 hr = IOleCache2_Uncache( cache, conn[1] ); 2811 ok( hr == S_OK, "got %08x\n", hr ); 2812 hr = IOleCache2_Uncache( cache, conn[0] ); 2813 ok( hr == S_OK, "got %08x\n", hr ); 2814 2815 /* View caching */ 2816 fmt.cfFormat = 0; 2817 fmt.ptd = NULL; 2818 fmt.dwAspect = DVASPECT_CONTENT; 2819 fmt.lindex = -1; 2820 fmt.tymed = TYMED_HGLOBAL; 2821 2822 hr = IOleCache2_Cache( cache, &fmt, 0, &conn[0] ); 2823 ok( hr == S_OK, "got %08x\n", hr ); 2824 view_cache[0].dwConnection = conn[0]; 2825 2826 g_dataobject_fmts = NULL; 2827 expected_method_list = methods_viewcache; 2828 2829 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); 2830 ok( hr == CACHE_E_NOCACHE_UPDATED, "got %08x\n", hr ); 2831 2832 CHECK_NO_EXTRA_METHODS(); 2833 check_enum_cache( cache, view_cache, 1 ); 2834 2835 g_dataobject_fmts = dib_fmt; 2836 expected_method_list = methods_viewcache_with_dib; 2837 2838 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); 2839 ok( hr == S_OK, "got %08x\n", hr ); 2840 2841 CHECK_NO_EXTRA_METHODS(); 2842 view_cache_after_dib[0].dwConnection = view_cache_after_dib[1].dwConnection = view_cache[0].dwConnection; 2843 check_enum_cache( cache, view_cache_after_dib, 2 ); 2844 2845 hr = IOleCache2_Uncache( cache, conn[0] ); 2846 ok( hr == S_OK, "got %08x\n", hr ); 2847 2848 /* Try some different flags */ 2849 2850 fmt.cfFormat = CF_DIB; 2851 fmt.ptd = NULL; 2852 fmt.dwAspect = DVASPECT_CONTENT; 2853 fmt.lindex = -1; 2854 fmt.tymed = TYMED_HGLOBAL; 2855 2856 hr = IOleCache2_Cache( cache, &fmt, 0, &conn[0] ); 2857 ok( hr == S_OK, "got %08x\n", hr ); 2858 2859 fmt.cfFormat = CF_ENHMETAFILE; 2860 fmt.ptd = NULL; 2861 fmt.dwAspect = DVASPECT_CONTENT; 2862 fmt.lindex = -1; 2863 fmt.tymed = TYMED_ENHMF; 2864 2865 hr = IOleCache2_Cache( cache, &fmt, ADVF_NODATA, &conn[1] ); 2866 ok( hr == S_OK, "got %08x\n", hr ); 2867 2868 fmt.cfFormat = CF_METAFILEPICT; 2869 fmt.ptd = NULL; 2870 fmt.dwAspect = DVASPECT_CONTENT; 2871 fmt.lindex = -1; 2872 fmt.tymed = TYMED_MFPICT; 2873 2874 hr = IOleCache2_Cache( cache, &fmt, ADVFCACHE_ONSAVE, &conn[2] ); 2875 ok( hr == S_OK, "got %08x\n", hr ); 2876 2877 g_dataobject_fmts = dib_fmt; 2878 expected_method_list = methods_flags_all; 2879 2880 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); 2881 2882 CHECK_NO_EXTRA_METHODS(); 2883 2884 expected_method_list = methods_flags_all; 2885 2886 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ALL, NULL ); 2887 ok( hr == S_OK, "got %08x\n", hr ); 2888 2889 CHECK_NO_EXTRA_METHODS(); 2890 2891 expected_method_list = methods_flags_ifblank_1; 2892 2893 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_IFBLANK , NULL ); 2894 ok( hr == S_OK, "got %08x\n", hr ); 2895 2896 CHECK_NO_EXTRA_METHODS(); 2897 2898 hr = IOleCache2_DiscardCache( cache, DISCARDCACHE_NOSAVE ); 2899 ok( hr == S_OK, "got %08x\n", hr ); 2900 2901 expected_method_list = methods_flags_ifblank_2; 2902 2903 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_IFBLANK , NULL ); 2904 ok( hr == S_OK, "got %08x\n", hr ); 2905 2906 CHECK_NO_EXTRA_METHODS(); 2907 2908 hr = IOleCache2_DiscardCache( cache, DISCARDCACHE_NOSAVE ); 2909 ok( hr == S_OK, "got %08x\n", hr ); 2910 2911 expected_method_list = methods_flags_all; 2912 2913 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_IFBLANK | UPDFCACHE_NODATACACHE, NULL ); 2914 ok( hr == S_OK, "got %08x\n", hr ); 2915 2916 CHECK_NO_EXTRA_METHODS(); 2917 2918 expected_method_list = methods_empty; 2919 2920 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ONLYIFBLANK | UPDFCACHE_NORMALCACHE, NULL ); 2921 ok( hr == S_OK, "got %08x\n", hr ); 2922 2923 CHECK_NO_EXTRA_METHODS(); 2924 2925 hr = IOleCache2_DiscardCache( cache, DISCARDCACHE_NOSAVE ); 2926 ok( hr == S_OK, "got %08x\n", hr ); 2927 2928 expected_method_list = methods_flags_normal; 2929 2930 hr = IOleCache2_UpdateCache( cache, &DataObject, UPDFCACHE_ONLYIFBLANK | UPDFCACHE_NORMALCACHE, NULL ); 2931 ok( hr == S_OK, "got %08x\n", hr ); 2932 2933 CHECK_NO_EXTRA_METHODS(); 2934 2935 expected_method_list = methods_initcache; 2936 2937 hr = IOleCache2_InitCache( cache, &DataObject ); 2938 ok( hr == S_OK, "got %08x\n", hr ); 2939 2940 CHECK_NO_EXTRA_METHODS(); 2941 2942 IOleCache2_Release( cache ); 2943 } 2944 2945 static void test_default_handler(void) 2946 { 2947 HRESULT hr; 2948 IOleObject *pObject; 2949 IRunnableObject *pRunnableObject; 2950 IOleClientSite *pClientSite; 2951 IDataObject *pDataObject; 2952 SIZEL sizel; 2953 DWORD dwStatus; 2954 CLSID clsid; 2955 LPOLESTR pszUserType; 2956 LOGPALETTE palette; 2957 DWORD dwAdvConn; 2958 IMoniker *pMoniker; 2959 FORMATETC fmtetc; 2960 IOleInPlaceObject *pInPlaceObj; 2961 IEnumOLEVERB *pEnumVerbs; 2962 DWORD dwRegister; 2963 static const WCHAR wszUnknown[] = {'U','n','k','n','o','w','n',0}; 2964 static const WCHAR wszHostName[] = {'W','i','n','e',' ','T','e','s','t',' ','P','r','o','g','r','a','m',0}; 2965 static const WCHAR wszDelim[] = {'!',0}; 2966 2967 static const struct expected_method methods_embeddinghelper[] = 2968 { 2969 { "OleObject_QueryInterface", 0 }, 2970 { "OleObject_AddRef", 0 }, 2971 { "OleObject_QueryInterface", 0 }, 2972 { "OleObject_QueryInterface", TEST_TODO }, 2973 { "OleObject_QueryInterface", 0 }, 2974 { "OleObject_QueryInterface", 0 }, 2975 { "OleObject_QueryInterface", TEST_OPTIONAL }, /* Win95/98/NT4 */ 2976 { "OleObject_Release", TEST_TODO }, 2977 { "WINE_EXTRA", TEST_OPTIONAL }, 2978 { NULL, 0 } 2979 }; 2980 2981 hr = CoCreateInstance(&CLSID_WineTest, NULL, CLSCTX_INPROC_HANDLER, &IID_IOleObject, (void **)&pObject); 2982 ok(hr == REGDB_E_CLASSNOTREG, "CoCreateInstance should have failed with REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); 2983 2984 hr = OleCreateDefaultHandler(&CLSID_WineTest, NULL, &IID_IOleObject, (void **)&pObject); 2985 ok_ole_success(hr, "OleCreateDefaultHandler"); 2986 2987 hr = IOleObject_QueryInterface(pObject, &IID_IOleInPlaceObject, (void **)&pInPlaceObj); 2988 ok(hr == E_NOINTERFACE, "IOleObject_QueryInterface(&IID_IOleInPlaceObject) should return E_NOINTERFACE instead of 0x%08x\n", hr); 2989 2990 hr = IOleObject_Advise(pObject, &AdviseSink, &dwAdvConn); 2991 ok_ole_success(hr, "IOleObject_Advise"); 2992 2993 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE); 2994 ok_ole_success(hr, "IOleObject_Close"); 2995 2996 /* FIXME: test IOleObject_EnumAdvise */ 2997 2998 hr = IOleObject_EnumVerbs(pObject, &pEnumVerbs); 2999 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_EnumVerbs should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); 3000 3001 hr = IOleObject_GetClientSite(pObject, &pClientSite); 3002 ok_ole_success(hr, "IOleObject_GetClientSite"); 3003 3004 hr = IOleObject_SetClientSite(pObject, pClientSite); 3005 ok_ole_success(hr, "IOleObject_SetClientSite"); 3006 3007 hr = IOleObject_GetClipboardData(pObject, 0, &pDataObject); 3008 ok(hr == OLE_E_NOTRUNNING, 3009 "IOleObject_GetClipboardData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", 3010 hr); 3011 3012 hr = IOleObject_GetExtent(pObject, DVASPECT_CONTENT, &sizel); 3013 ok(hr == OLE_E_BLANK, "IOleObject_GetExtent should have returned OLE_E_BLANK instead of 0x%08x\n", 3014 hr); 3015 3016 hr = IOleObject_GetMiscStatus(pObject, DVASPECT_CONTENT, &dwStatus); 3017 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_GetMiscStatus should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); 3018 3019 hr = IOleObject_GetUserClassID(pObject, &clsid); 3020 ok_ole_success(hr, "IOleObject_GetUserClassID"); 3021 ok(IsEqualCLSID(&clsid, &CLSID_WineTest), "clsid != CLSID_WineTest\n"); 3022 3023 hr = IOleObject_GetUserType(pObject, USERCLASSTYPE_FULL, &pszUserType); 3024 todo_wine { 3025 ok_ole_success(hr, "IOleObject_GetUserType"); 3026 ok(!lstrcmpW(pszUserType, wszUnknown), "Retrieved user type was wrong\n"); 3027 } 3028 3029 hr = IOleObject_InitFromData(pObject, NULL, TRUE, 0); 3030 ok(hr == OLE_E_NOTRUNNING, "IOleObject_InitFromData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); 3031 3032 hr = IOleObject_IsUpToDate(pObject); 3033 ok(hr == OLE_E_NOTRUNNING, "IOleObject_IsUpToDate should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); 3034 3035 palette.palNumEntries = 1; 3036 palette.palVersion = 2; 3037 memset(&palette.palPalEntry[0], 0, sizeof(palette.palPalEntry[0])); 3038 hr = IOleObject_SetColorScheme(pObject, &palette); 3039 ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetColorScheme should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); 3040 3041 sizel.cx = sizel.cy = 0; 3042 hr = IOleObject_SetExtent(pObject, DVASPECT_CONTENT, &sizel); 3043 ok(hr == OLE_E_NOTRUNNING, "IOleObject_SetExtent should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); 3044 3045 hr = IOleObject_SetHostNames(pObject, wszHostName, NULL); 3046 ok_ole_success(hr, "IOleObject_SetHostNames"); 3047 3048 hr = CreateItemMoniker(wszDelim, wszHostName, &pMoniker); 3049 ok_ole_success(hr, "CreateItemMoniker"); 3050 hr = IOleObject_SetMoniker(pObject, OLEWHICHMK_CONTAINER, pMoniker); 3051 ok_ole_success(hr, "IOleObject_SetMoniker"); 3052 IMoniker_Release(pMoniker); 3053 3054 hr = IOleObject_GetMoniker(pObject, OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_CONTAINER, &pMoniker); 3055 ok(hr == E_FAIL, "IOleObject_GetMoniker should have returned E_FAIL instead of 0x%08x\n", hr); 3056 3057 hr = IOleObject_Update(pObject); 3058 todo_wine 3059 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Update should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); 3060 3061 hr = IOleObject_QueryInterface(pObject, &IID_IDataObject, (void **)&pDataObject); 3062 ok_ole_success(hr, "IOleObject_QueryInterface"); 3063 3064 fmtetc.cfFormat = CF_TEXT; 3065 fmtetc.ptd = NULL; 3066 fmtetc.dwAspect = DVASPECT_CONTENT; 3067 fmtetc.lindex = -1; 3068 fmtetc.tymed = TYMED_NULL; 3069 hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn); 3070 ok_ole_success(hr, "IDataObject_DAdvise"); 3071 3072 fmtetc.cfFormat = CF_ENHMETAFILE; 3073 fmtetc.ptd = NULL; 3074 fmtetc.dwAspect = DVASPECT_CONTENT; 3075 fmtetc.lindex = -1; 3076 fmtetc.tymed = TYMED_ENHMF; 3077 hr = IDataObject_DAdvise(pDataObject, &fmtetc, 0, &AdviseSink, &dwAdvConn); 3078 ok_ole_success(hr, "IDataObject_DAdvise"); 3079 3080 fmtetc.cfFormat = CF_ENHMETAFILE; 3081 fmtetc.ptd = NULL; 3082 fmtetc.dwAspect = DVASPECT_CONTENT; 3083 fmtetc.lindex = -1; 3084 fmtetc.tymed = TYMED_ENHMF; 3085 hr = IDataObject_QueryGetData(pDataObject, &fmtetc); 3086 ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); 3087 3088 fmtetc.cfFormat = CF_TEXT; 3089 fmtetc.ptd = NULL; 3090 fmtetc.dwAspect = DVASPECT_CONTENT; 3091 fmtetc.lindex = -1; 3092 fmtetc.tymed = TYMED_NULL; 3093 hr = IDataObject_QueryGetData(pDataObject, &fmtetc); 3094 ok(hr == OLE_E_NOTRUNNING, "IDataObject_QueryGetData should have returned OLE_E_NOTRUNNING instead of 0x%08x\n", hr); 3095 3096 hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnableObject); 3097 ok_ole_success(hr, "IOleObject_QueryInterface"); 3098 3099 hr = IRunnableObject_SetContainedObject(pRunnableObject, TRUE); 3100 ok_ole_success(hr, "IRunnableObject_SetContainedObject"); 3101 3102 hr = IRunnableObject_Run(pRunnableObject, NULL); 3103 ok(hr == REGDB_E_CLASSNOTREG, "IOleObject_Run should have returned REGDB_E_CLASSNOTREG instead of 0x%08x\n", hr); 3104 3105 hr = IOleObject_Close(pObject, OLECLOSE_NOSAVE); 3106 ok_ole_success(hr, "IOleObject_Close"); 3107 3108 IRunnableObject_Release(pRunnableObject); 3109 IOleObject_Release(pObject); 3110 3111 /* Test failure propagation from delegate ::QueryInterface */ 3112 hr = CoRegisterClassObject(&CLSID_WineTest, (IUnknown*)&OleObjectCF, 3113 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister); 3114 ok_ole_success(hr, "CoRegisterClassObject"); 3115 if(SUCCEEDED(hr)) 3116 { 3117 expected_method_list = methods_embeddinghelper; 3118 hr = OleCreateEmbeddingHelper(&CLSID_WineTest, NULL, EMBDHLP_INPROC_SERVER, 3119 &OleObjectCF, &IID_IOleObject, (void**)&pObject); 3120 ok_ole_success(hr, "OleCreateEmbeddingHelper"); 3121 if(SUCCEEDED(hr)) 3122 { 3123 IUnknown *punk; 3124 3125 g_QIFailsWith = E_FAIL; 3126 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk); 3127 ok(hr == E_FAIL, "Got 0x%08x\n", hr); 3128 3129 g_QIFailsWith = E_NOINTERFACE; 3130 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk); 3131 ok(hr == E_NOINTERFACE, "Got 0x%08x\n", hr); 3132 3133 g_QIFailsWith = CO_E_OBJNOTCONNECTED; 3134 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk); 3135 ok(hr == CO_E_OBJNOTCONNECTED, "Got 0x%08x\n", hr); 3136 3137 g_QIFailsWith = 0x87654321; 3138 hr = IOleObject_QueryInterface(pObject, &IID_WineTest, (void**)&punk); 3139 ok(hr == 0x87654321, "Got 0x%08x\n", hr); 3140 3141 IOleObject_Release(pObject); 3142 } 3143 3144 CHECK_NO_EXTRA_METHODS(); 3145 3146 hr = CoRevokeClassObject(dwRegister); 3147 ok_ole_success(hr, "CoRevokeClassObject"); 3148 } 3149 } 3150 3151 static void test_runnable(void) 3152 { 3153 static const struct expected_method methods_query_runnable[] = 3154 { 3155 { "OleObject_QueryInterface", 0 }, 3156 { "OleObjectRunnable_AddRef", 0 }, 3157 { "OleObjectRunnable_IsRunning", 0 }, 3158 { "OleObjectRunnable_Release", 0 }, 3159 { NULL, 0 } 3160 }; 3161 3162 static const struct expected_method methods_no_runnable[] = 3163 { 3164 { "OleObject_QueryInterface", 0 }, 3165 { NULL, 0 } 3166 }; 3167 3168 BOOL ret; 3169 IOleObject *object = &OleObject; 3170 3171 /* null argument */ 3172 ret = OleIsRunning(NULL); 3173 ok(ret == FALSE, "got %d\n", ret); 3174 3175 expected_method_list = methods_query_runnable; 3176 ret = OleIsRunning(object); 3177 ok(ret == TRUE, "Object should be running\n"); 3178 CHECK_NO_EXTRA_METHODS(); 3179 3180 g_isRunning = FALSE; 3181 expected_method_list = methods_query_runnable; 3182 ret = OleIsRunning(object); 3183 ok(ret == FALSE, "Object should not be running\n"); 3184 CHECK_NO_EXTRA_METHODS(); 3185 3186 g_showRunnable = FALSE; /* QueryInterface(IID_IRunnableObject, ...) will fail */ 3187 expected_method_list = methods_no_runnable; 3188 ret = OleIsRunning(object); 3189 ok(ret == TRUE, "Object without IRunnableObject should be running\n"); 3190 CHECK_NO_EXTRA_METHODS(); 3191 3192 g_isRunning = TRUE; 3193 g_showRunnable = TRUE; 3194 } 3195 3196 3197 static HRESULT WINAPI OleRun_QueryInterface(IRunnableObject *iface, REFIID riid, void **ppv) 3198 { 3199 *ppv = NULL; 3200 3201 if (IsEqualIID(riid, &IID_IUnknown) || 3202 IsEqualIID(riid, &IID_IRunnableObject)) { 3203 *ppv = iface; 3204 } 3205 3206 if (*ppv) 3207 { 3208 IUnknown_AddRef((IUnknown *)*ppv); 3209 return S_OK; 3210 } 3211 3212 return E_NOINTERFACE; 3213 } 3214 3215 static ULONG WINAPI OleRun_AddRef(IRunnableObject *iface) 3216 { 3217 return 2; 3218 } 3219 3220 static ULONG WINAPI OleRun_Release(IRunnableObject *iface) 3221 { 3222 return 1; 3223 } 3224 3225 static HRESULT WINAPI OleRun_GetRunningClass(IRunnableObject *iface, CLSID *clsid) 3226 { 3227 ok(0, "unexpected\n"); 3228 return E_NOTIMPL; 3229 } 3230 3231 static HRESULT WINAPI OleRun_Run(IRunnableObject *iface, LPBINDCTX ctx) 3232 { 3233 ok(ctx == NULL, "got %p\n", ctx); 3234 return 0xdeadc0de; 3235 } 3236 3237 static BOOL WINAPI OleRun_IsRunning(IRunnableObject *iface) 3238 { 3239 ok(0, "unexpected\n"); 3240 return FALSE; 3241 } 3242 3243 static HRESULT WINAPI OleRun_LockRunning(IRunnableObject *iface, BOOL lock, 3244 BOOL last_unlock_closes) 3245 { 3246 ok(0, "unexpected\n"); 3247 return E_NOTIMPL; 3248 } 3249 3250 static HRESULT WINAPI OleRun_SetContainedObject(IRunnableObject *iface, BOOL contained) 3251 { 3252 ok(0, "unexpected\n"); 3253 return E_NOTIMPL; 3254 } 3255 3256 static const IRunnableObjectVtbl oleruntestvtbl = 3257 { 3258 OleRun_QueryInterface, 3259 OleRun_AddRef, 3260 OleRun_Release, 3261 OleRun_GetRunningClass, 3262 OleRun_Run, 3263 OleRun_IsRunning, 3264 OleRun_LockRunning, 3265 OleRun_SetContainedObject 3266 }; 3267 3268 static IRunnableObject testrunnable = { &oleruntestvtbl }; 3269 3270 static void test_OleRun(void) 3271 { 3272 HRESULT hr; 3273 3274 /* doesn't support IRunnableObject */ 3275 hr = OleRun(&unknown); 3276 ok(hr == S_OK, "OleRun failed 0x%08x\n", hr); 3277 3278 hr = OleRun((IUnknown*)&testrunnable); 3279 ok(hr == 0xdeadc0de, "got 0x%08x\n", hr); 3280 } 3281 3282 static void test_OleLockRunning(void) 3283 { 3284 HRESULT hr; 3285 3286 hr = OleLockRunning(&unknown, TRUE, FALSE); 3287 ok(hr == S_OK, "OleLockRunning failed 0x%08x\n", hr); 3288 } 3289 3290 static void test_OleDraw(void) 3291 { 3292 HRESULT hr; 3293 RECT rect; 3294 3295 hr = OleDraw((IUnknown*)&viewobject, 0, (HDC)0x1, NULL); 3296 ok(hr == S_OK, "got 0x%08x\n", hr); 3297 3298 hr = OleDraw(NULL, 0, (HDC)0x1, NULL); 3299 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 3300 3301 hr = OleDraw(NULL, 0, (HDC)0x1, &rect); 3302 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); 3303 } 3304 3305 static const WCHAR olepres0W[] = {2,'O','l','e','P','r','e','s','0','0','0',0}; 3306 static const WCHAR comp_objW[] = {1,'C','o','m','p','O','b','j',0}; 3307 static IStream *comp_obj_stream; 3308 static IStream *ole_stream; 3309 static IStream *olepres_stream; 3310 static IStream *contents_stream; 3311 3312 static HRESULT WINAPI Storage_QueryInterface(IStorage *iface, REFIID riid, void **ppvObject) 3313 { 3314 ok(0, "unexpected call to QueryInterface\n"); 3315 return E_NOTIMPL; 3316 } 3317 3318 static ULONG WINAPI Storage_AddRef(IStorage *iface) 3319 { 3320 ok(0, "unexpected call to AddRef\n"); 3321 return 2; 3322 } 3323 3324 static ULONG WINAPI Storage_Release(IStorage *iface) 3325 { 3326 ok(0, "unexpected call to Release\n"); 3327 return 1; 3328 } 3329 3330 static HRESULT WINAPI Storage_CreateStream(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm) 3331 { 3332 ULARGE_INTEGER size = {{0}}; 3333 LARGE_INTEGER pos = {{0}}; 3334 HRESULT hr; 3335 3336 if (!lstrcmpW(pwcsName, comp_objW)) 3337 { 3338 CHECK_EXPECT(Storage_CreateStream_CompObj); 3339 *ppstm = comp_obj_stream; 3340 3341 todo_wine ok(grfMode == (STGM_CREATE|STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode); 3342 } 3343 else if (!lstrcmpW(pwcsName, olepres0W)) 3344 { 3345 CHECK_EXPECT(Storage_CreateStream_OlePres); 3346 *ppstm = olepres_stream; 3347 3348 todo_wine ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode); 3349 } 3350 else 3351 { 3352 todo_wine 3353 ok(0, "unexpected stream name %s\n", wine_dbgstr_w(pwcsName)); 3354 #if 0 /* FIXME: return NULL once Wine is fixed */ 3355 *ppstm = NULL; 3356 return E_NOTIMPL; 3357 #else 3358 *ppstm = contents_stream; 3359 #endif 3360 } 3361 3362 ok(!reserved1, "reserved1 = %x\n", reserved1); 3363 ok(!reserved2, "reserved2 = %x\n", reserved2); 3364 ok(!!ppstm, "ppstm = NULL\n"); 3365 3366 IStream_AddRef(*ppstm); 3367 hr = IStream_Seek(*ppstm, pos, STREAM_SEEK_SET, NULL); 3368 ok(hr == S_OK, "IStream_Seek returned %x\n", hr); 3369 hr = IStream_SetSize(*ppstm, size); 3370 ok(hr == S_OK, "IStream_SetSize returned %x\n", hr); 3371 return S_OK; 3372 } 3373 3374 static HRESULT WINAPI Storage_OpenStream(IStorage *iface, LPCOLESTR pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm) 3375 { 3376 static const WCHAR ole1W[] = {1,'O','l','e',0}; 3377 3378 LARGE_INTEGER pos = {{0}}; 3379 HRESULT hr; 3380 3381 ok(!reserved1, "reserved1 = %p\n", reserved1); 3382 ok(!reserved2, "reserved2 = %x\n", reserved2); 3383 ok(!!ppstm, "ppstm = NULL\n"); 3384 3385 if(!lstrcmpW(pwcsName, comp_objW)) { 3386 CHECK_EXPECT2(Storage_OpenStream_CompObj); 3387 ok(grfMode == STGM_SHARE_EXCLUSIVE, "grfMode = %x\n", grfMode); 3388 3389 *ppstm = comp_obj_stream; 3390 IStream_AddRef(comp_obj_stream); 3391 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL); 3392 ok(hr == S_OK, "IStream_Seek returned %x\n", hr); 3393 return S_OK; 3394 }else if(!lstrcmpW(pwcsName, ole1W)) { 3395 CHECK_EXPECT(Storage_OpenStream_Ole); 3396 3397 if (!ole_stream) 3398 { 3399 ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READ), "grfMode = %x\n", grfMode); 3400 3401 *ppstm = NULL; 3402 return STG_E_FILENOTFOUND; 3403 } 3404 3405 ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode); 3406 3407 *ppstm = ole_stream; 3408 IStream_AddRef(ole_stream); 3409 hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL); 3410 ok(hr == S_OK, "IStream_Seek returned %x\n", hr); 3411 return S_OK; 3412 3413 }else if(!lstrcmpW(pwcsName, olepres0W)) { 3414 CHECK_EXPECT(Storage_OpenStream_OlePres); 3415 ok(grfMode == (STGM_SHARE_EXCLUSIVE|STGM_READWRITE), "grfMode = %x\n", grfMode); 3416 3417 *ppstm = olepres_stream; 3418 IStream_AddRef(olepres_stream); 3419 hr = IStream_Seek(olepres_stream, pos, STREAM_SEEK_SET, NULL); 3420 ok(hr == S_OK, "IStream_Seek returned %x\n", hr); 3421 return S_OK; 3422 } 3423 3424 ok(0, "unexpected call to OpenStream: %s\n", wine_dbgstr_w(pwcsName)); 3425 return E_NOTIMPL; 3426 } 3427 3428 static HRESULT WINAPI Storage_CreateStorage(IStorage *iface, LPCOLESTR pwcsName, DWORD grfMode, DWORD dwStgFmt, DWORD reserved2, IStorage **ppstg) 3429 { 3430 ok(0, "unexpected call to CreateStorage\n"); 3431 return E_NOTIMPL; 3432 } 3433 3434 static HRESULT WINAPI Storage_OpenStorage(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgPriority, DWORD grfMode, SNB snbExclude, DWORD reserved, IStorage **ppstg) 3435 { 3436 ok(0, "unexpected call to OpenStorage\n"); 3437 return E_NOTIMPL; 3438 } 3439 3440 static HRESULT WINAPI Storage_CopyTo(IStorage *iface, DWORD ciidExclude, const IID *rgiidExclude, SNB snbExclude, IStorage *pstgDest) 3441 { 3442 ok(0, "unexpected call to CopyTo\n"); 3443 return E_NOTIMPL; 3444 } 3445 3446 static HRESULT WINAPI Storage_MoveElementTo(IStorage *iface, LPCOLESTR pwcsName, IStorage *pstgDest, LPCOLESTR pwcsNewName, DWORD grfFlags) 3447 { 3448 ok(0, "unexpected call to MoveElementTo\n"); 3449 return E_NOTIMPL; 3450 } 3451 3452 static HRESULT WINAPI Storage_Commit(IStorage *iface, DWORD grfCommitFlags) 3453 { 3454 ok(0, "unexpected call to Commit\n"); 3455 return E_NOTIMPL; 3456 } 3457 3458 static HRESULT WINAPI Storage_Revert(IStorage *iface) 3459 { 3460 ok(0, "unexpected call to Revert\n"); 3461 return E_NOTIMPL; 3462 } 3463 3464 static HRESULT WINAPI Storage_EnumElements(IStorage *iface, DWORD reserved1, void *reserved2, DWORD reserved3, IEnumSTATSTG **ppenum) 3465 { 3466 ok(0, "unexpected call to EnumElements\n"); 3467 return E_NOTIMPL; 3468 } 3469 3470 static HRESULT WINAPI Storage_DestroyElement(IStorage *iface, LPCOLESTR pwcsName) 3471 { 3472 char name[32]; 3473 int stream_n, cmp; 3474 3475 CHECK_EXPECT2(Storage_DestroyElement); 3476 cmp = CompareStringW(LOCALE_NEUTRAL, 0, pwcsName, 8, olepres0W, 8); 3477 ok(cmp == CSTR_EQUAL, 3478 "unexpected call to DestroyElement(%s)\n", wine_dbgstr_w(pwcsName)); 3479 3480 WideCharToMultiByte(CP_ACP, 0, pwcsName, -1, name, sizeof(name), NULL, NULL); 3481 stream_n = atol(name + 8); 3482 if (stream_n <= Storage_DestroyElement_limit) 3483 return S_OK; 3484 3485 return STG_E_FILENOTFOUND; 3486 } 3487 3488 static HRESULT WINAPI Storage_RenameElement(IStorage *iface, LPCOLESTR pwcsOldName, LPCOLESTR pwcsNewName) 3489 { 3490 ok(0, "unexpected call to RenameElement\n"); 3491 return E_NOTIMPL; 3492 } 3493 3494 static HRESULT WINAPI Storage_SetElementTimes(IStorage *iface, LPCOLESTR pwcsName, const FILETIME *pctime, const FILETIME *patime, const FILETIME *pmtime) 3495 { 3496 ok(0, "unexpected call to SetElementTimes\n"); 3497 return E_NOTIMPL; 3498 } 3499 3500 static HRESULT WINAPI Storage_SetClass(IStorage *iface, REFCLSID clsid) 3501 { 3502 CHECK_EXPECT(Storage_SetClass); 3503 ok(IsEqualIID(clsid, Storage_SetClass_CLSID), "expected %s, got %s\n", 3504 wine_dbgstr_guid(Storage_SetClass_CLSID), wine_dbgstr_guid(clsid)); 3505 return S_OK; 3506 } 3507 3508 static HRESULT WINAPI Storage_SetStateBits(IStorage *iface, DWORD grfStateBits, DWORD grfMask) 3509 { 3510 ok(0, "unexpected call to SetStateBits\n"); 3511 return E_NOTIMPL; 3512 } 3513 3514 static HRESULT WINAPI Storage_Stat(IStorage *iface, STATSTG *pstatstg, DWORD grfStatFlag) 3515 { 3516 CHECK_EXPECT2(Storage_Stat); 3517 ok(pstatstg != NULL, "pstatstg = NULL\n"); 3518 ok(grfStatFlag == STATFLAG_NONAME, "grfStatFlag = %x\n", grfStatFlag); 3519 3520 memset(pstatstg, 0, sizeof(STATSTG)); 3521 pstatstg->type = STGTY_STORAGE; 3522 pstatstg->clsid = CLSID_WineTestOld; 3523 return S_OK; 3524 } 3525 3526 static IStorageVtbl StorageVtbl = 3527 { 3528 Storage_QueryInterface, 3529 Storage_AddRef, 3530 Storage_Release, 3531 Storage_CreateStream, 3532 Storage_OpenStream, 3533 Storage_CreateStorage, 3534 Storage_OpenStorage, 3535 Storage_CopyTo, 3536 Storage_MoveElementTo, 3537 Storage_Commit, 3538 Storage_Revert, 3539 Storage_EnumElements, 3540 Storage_DestroyElement, 3541 Storage_RenameElement, 3542 Storage_SetElementTimes, 3543 Storage_SetClass, 3544 Storage_SetStateBits, 3545 Storage_Stat 3546 }; 3547 3548 static IStorage Storage = { &StorageVtbl }; 3549 3550 static void test_OleDoAutoConvert(void) 3551 { 3552 static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0}; 3553 static struct { 3554 DWORD reserved1; 3555 DWORD version; 3556 DWORD reserved2[5]; 3557 DWORD ansi_user_type_len; 3558 DWORD ansi_clipboard_format_len; 3559 DWORD reserved3; 3560 DWORD unicode_marker; 3561 DWORD unicode_user_type_len; 3562 DWORD unicode_clipboard_format_len; 3563 DWORD reserved4; 3564 } comp_obj_data; 3565 static struct { 3566 DWORD version; 3567 DWORD flags; 3568 DWORD link_update_option; 3569 DWORD reserved1; 3570 DWORD reserved_moniker_stream_size; 3571 DWORD relative_source_moniker_stream_size; 3572 DWORD absolute_source_moniker_stream_size; 3573 DWORD clsid_indicator; 3574 CLSID clsid; 3575 DWORD reserved_display_name; 3576 DWORD reserved2; 3577 DWORD local_update_time; 3578 DWORD local_check_update_time; 3579 DWORD remote_update_time; 3580 } ole_data; 3581 3582 LARGE_INTEGER pos = {{0}}; 3583 WCHAR buf[39+6]; 3584 DWORD i, ret; 3585 HKEY root; 3586 CLSID clsid; 3587 HRESULT hr; 3588 3589 hr = CreateStreamOnHGlobal(NULL, TRUE, &comp_obj_stream); 3590 ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr); 3591 hr = IStream_Write(comp_obj_stream, (char*)&comp_obj_data, sizeof(comp_obj_data), NULL); 3592 ok(hr == S_OK, "IStream_Write returned %x\n", hr); 3593 3594 hr = CreateStreamOnHGlobal(NULL, TRUE, &ole_stream); 3595 ok(hr == S_OK, "CreateStreamOnHGlobal returned %x\n", hr); 3596 hr = IStream_Write(ole_stream, (char*)&ole_data, sizeof(ole_data), NULL); 3597 ok(hr == S_OK, "IStream_Write returned %x\n", hr); 3598 3599 clsid = IID_WineTest; 3600 hr = OleDoAutoConvert(NULL, &clsid); 3601 ok(hr == E_INVALIDARG, "OleDoAutoConvert returned %x\n", hr); 3602 ok(IsEqualIID(&clsid, &IID_NULL), "clsid = %s\n", wine_dbgstr_guid(&clsid)); 3603 3604 if(0) /* crashes on Win7 */ 3605 OleDoAutoConvert(&Storage, NULL); 3606 3607 clsid = IID_WineTest; 3608 SET_EXPECT(Storage_Stat); 3609 hr = OleDoAutoConvert(&Storage, &clsid); 3610 ok(hr == REGDB_E_CLASSNOTREG, "OleDoAutoConvert returned %x\n", hr); 3611 CHECK_CALLED(Storage_Stat); 3612 ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid)); 3613 3614 lstrcpyW(buf, clsidW); 3615 StringFromGUID2(&CLSID_WineTestOld, buf+6, 39); 3616 3617 ret = RegCreateKeyExW(HKEY_CLASSES_ROOT, buf, 0, NULL, 0, 3618 KEY_READ | KEY_WRITE | KEY_CREATE_SUB_KEY, NULL, &root, NULL); 3619 if(ret != ERROR_SUCCESS) { 3620 win_skip("not enough permissions to create CLSID key (%u)\n", ret); 3621 return; 3622 } 3623 3624 clsid = IID_WineTest; 3625 SET_EXPECT(Storage_Stat); 3626 hr = OleDoAutoConvert(&Storage, &clsid); 3627 ok(hr == REGDB_E_KEYMISSING, "OleDoAutoConvert returned %x\n", hr); 3628 CHECK_CALLED(Storage_Stat); 3629 ok(IsEqualIID(&clsid, &CLSID_WineTestOld), "clsid = %s\n", wine_dbgstr_guid(&clsid)); 3630 3631 hr = OleSetAutoConvert(&CLSID_WineTestOld, &CLSID_WineTest); 3632 ok_ole_success(hr, "OleSetAutoConvert"); 3633 3634 hr = OleGetAutoConvert(&CLSID_WineTestOld, &clsid); 3635 ok_ole_success(hr, "OleGetAutoConvert"); 3636 ok(IsEqualIID(&clsid, &CLSID_WineTest), "incorrect clsid: %s\n", wine_dbgstr_guid(&clsid)); 3637 3638 clsid = IID_WineTest; 3639 SET_EXPECT(Storage_Stat); 3640 SET_EXPECT(Storage_OpenStream_CompObj); 3641 SET_EXPECT(Storage_SetClass); 3642 SET_EXPECT(Storage_CreateStream_CompObj); 3643 SET_EXPECT(Storage_OpenStream_Ole); 3644 hr = OleDoAutoConvert(&Storage, &clsid); 3645 ok(hr == S_OK, "OleDoAutoConvert returned %x\n", hr); 3646 CHECK_CALLED(Storage_Stat); 3647 CHECK_CALLED(Storage_OpenStream_CompObj); 3648 CHECK_CALLED(Storage_SetClass); 3649 CHECK_CALLED(Storage_CreateStream_CompObj); 3650 CHECK_CALLED(Storage_OpenStream_Ole); 3651 ok(IsEqualIID(&clsid, &CLSID_WineTest), "clsid = %s\n", wine_dbgstr_guid(&clsid)); 3652 3653 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL); 3654 ok(hr == S_OK, "IStream_Seek returned %x\n", hr); 3655 hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL); 3656 ok(hr == S_OK, "IStream_Read returned %x\n", hr); 3657 ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1); 3658 ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version); 3659 ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]); 3660 ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1))); 3661 ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len); 3662 ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len); 3663 ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3); 3664 ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker); 3665 ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len); 3666 ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len); 3667 ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4); 3668 3669 hr = IStream_Seek(ole_stream, pos, STREAM_SEEK_SET, NULL); 3670 ok(hr == S_OK, "IStream_Seek returned %x\n", hr); 3671 hr = IStream_Read(ole_stream, &ole_data, sizeof(ole_data), NULL); 3672 ok(hr == S_OK, "IStream_Read returned %x\n", hr); 3673 ok(ole_data.version == 0, "version = %x\n", ole_data.version); 3674 ok(ole_data.flags == 4, "flags = %x\n", ole_data.flags); 3675 for(i=2; i<sizeof(ole_data)/sizeof(DWORD); i++) 3676 ok(((DWORD*)&ole_data)[i] == 0, "ole_data[%d] = %x\n", i, ((DWORD*)&ole_data)[i]); 3677 3678 SET_EXPECT(Storage_OpenStream_Ole); 3679 hr = SetConvertStg(&Storage, TRUE); 3680 ok(hr == S_OK, "SetConvertStg returned %x\n", hr); 3681 CHECK_CALLED(Storage_OpenStream_Ole); 3682 3683 SET_EXPECT(Storage_OpenStream_CompObj); 3684 SET_EXPECT(Storage_Stat); 3685 SET_EXPECT(Storage_CreateStream_CompObj); 3686 hr = WriteFmtUserTypeStg(&Storage, 0, NULL); 3687 ok(hr == S_OK, "WriteFmtUserTypeStg returned %x\n", hr); 3688 todo_wine CHECK_CALLED(Storage_OpenStream_CompObj); 3689 CHECK_CALLED(Storage_Stat); 3690 CHECK_CALLED(Storage_CreateStream_CompObj); 3691 hr = IStream_Seek(comp_obj_stream, pos, STREAM_SEEK_SET, NULL); 3692 ok(hr == S_OK, "IStream_Seek returned %x\n", hr); 3693 hr = IStream_Read(comp_obj_stream, &comp_obj_data, sizeof(comp_obj_data), NULL); 3694 ok(hr == S_OK, "IStream_Read returned %x\n", hr); 3695 ok(comp_obj_data.reserved1 == 0xfffe0001, "reserved1 = %x\n", comp_obj_data.reserved1); 3696 ok(comp_obj_data.version == 0xa03, "version = %x\n", comp_obj_data.version); 3697 ok(comp_obj_data.reserved2[0] == -1, "reserved2[0] = %x\n", comp_obj_data.reserved2[0]); 3698 ok(IsEqualIID(comp_obj_data.reserved2+1, &CLSID_WineTestOld), "reserved2 = %s\n", wine_dbgstr_guid((CLSID*)(comp_obj_data.reserved2+1))); 3699 ok(!comp_obj_data.ansi_user_type_len, "ansi_user_type_len = %d\n", comp_obj_data.ansi_user_type_len); 3700 ok(!comp_obj_data.ansi_clipboard_format_len, "ansi_clipboard_format_len = %d\n", comp_obj_data.ansi_clipboard_format_len); 3701 ok(!comp_obj_data.reserved3, "reserved3 = %x\n", comp_obj_data.reserved3); 3702 ok(comp_obj_data.unicode_marker == 0x71b239f4, "unicode_marker = %x\n", comp_obj_data.unicode_marker); 3703 ok(!comp_obj_data.unicode_user_type_len, "unicode_user_type_len = %d\n", comp_obj_data.unicode_user_type_len); 3704 ok(!comp_obj_data.unicode_clipboard_format_len, "unicode_clipboard_format_len = %d\n", comp_obj_data.unicode_clipboard_format_len); 3705 ok(!comp_obj_data.reserved4, "reserved4 %d\n", comp_obj_data.reserved4); 3706 3707 ret = IStream_Release(comp_obj_stream); 3708 ok(!ret, "comp_obj_stream was not freed\n"); 3709 ret = IStream_Release(ole_stream); 3710 ok(!ret, "ole_stream was not freed\n"); 3711 3712 ret = RegDeleteKeyA(root, "AutoConvertTo"); 3713 ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret); 3714 ret = RegDeleteKeyA(root, ""); 3715 ok(ret == ERROR_SUCCESS, "RegDeleteKey error %u\n", ret); 3716 RegCloseKey(root); 3717 } 3718 3719 /* 1x1 pixel bmp */ 3720 static const unsigned char bmpimage[] = 3721 { 3722 0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00, 3723 0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00, 3724 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00, 3725 0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00, 3726 0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b, 3727 0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00, 3728 0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff, 3729 0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x00, 3730 0x00,0x00 3731 }; 3732 3733 static const unsigned char mf_blank_bits[] = 3734 { 3735 0x01,0x00,0x09,0x00,0x00,0x03,0x0c,0x00, 3736 0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00, 3737 0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00 3738 }; 3739 3740 static void test_data_cache_save(void) 3741 { 3742 static const WCHAR contentsW[] = { 'C','o','n','t','e','n','t','s',0 }; 3743 HRESULT hr; 3744 ILockBytes *ilb; 3745 IStorage *doc; 3746 IStream *stm; 3747 IOleCache2 *cache; 3748 IPersistStorage *stg; 3749 DWORD clipformat[2]; 3750 PresentationDataHeader hdr; 3751 3752 hr = CreateILockBytesOnHGlobal(0, TRUE, &ilb); 3753 ok(hr == S_OK, "unexpected %#x\n", hr); 3754 hr = StgCreateDocfileOnILockBytes(ilb, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &doc); 3755 ok(hr == S_OK, "unexpected %#x\n", hr); 3756 3757 ILockBytes_Release(ilb); 3758 3759 hr = IStorage_SetClass(doc, &CLSID_WineTest); 3760 ok(hr == S_OK, "unexpected %#x\n", hr); 3761 3762 hr = IStorage_CreateStream(doc, contentsW, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm); 3763 ok(hr == S_OK, "unexpected %#x\n", hr); 3764 hr = IStream_Write(stm, bmpimage, sizeof(bmpimage), NULL); 3765 ok(hr == S_OK, "unexpected %#x\n", hr); 3766 IStream_Release(stm); 3767 3768 hr = IStorage_CreateStream(doc, olepres0W, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm); 3769 ok(hr == S_OK, "unexpected %#x\n", hr); 3770 3771 clipformat[0] = -1; 3772 clipformat[1] = CF_METAFILEPICT; 3773 hr = IStream_Write(stm, clipformat, sizeof(clipformat), NULL); 3774 ok(hr == S_OK, "unexpected %#x\n", hr); 3775 3776 hdr.tdSize = sizeof(hdr.tdSize); 3777 hdr.dvAspect = DVASPECT_CONTENT; 3778 hdr.lindex = -1; 3779 hdr.advf = ADVF_PRIMEFIRST; 3780 hdr.unknown7 = 0; 3781 hdr.dwObjectExtentX = 0; 3782 hdr.dwObjectExtentY = 0; 3783 hdr.dwSize = sizeof(mf_blank_bits); 3784 hr = IStream_Write(stm, &hdr, sizeof(hdr), NULL); 3785 ok(hr == S_OK, "unexpected %#x\n", hr); 3786 hr = IStream_Write(stm, mf_blank_bits, sizeof(mf_blank_bits), NULL); 3787 ok(hr == S_OK, "unexpected %#x\n", hr); 3788 3789 IStream_Release(stm); 3790 3791 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IUnknown, (void **)&cache); 3792 ok(hr == S_OK, "unexpected %#x\n", hr); 3793 hr = IOleCache2_QueryInterface(cache, &IID_IPersistStorage, (void **)&stg); 3794 ok(hr == S_OK, "unexpected %#x\n", hr); 3795 hr = IPersistStorage_Load(stg, doc); 3796 ok(hr == S_OK, "unexpected %#x\n", hr); 3797 3798 IStorage_Release(doc); 3799 3800 hr = IPersistStorage_IsDirty(stg); 3801 ok(hr == S_FALSE, "unexpected %#x\n", hr); 3802 3803 ole_stream = NULL; 3804 hr = CreateStreamOnHGlobal(NULL, TRUE, &olepres_stream); 3805 ok(hr == S_OK, "unexpected %#x\n", hr); 3806 3807 /* FIXME: remove this stream once Wine is fixed */ 3808 hr = CreateStreamOnHGlobal(NULL, TRUE, &contents_stream); 3809 ok(hr == S_OK, "unexpected %#x\n", hr); 3810 3811 SET_EXPECT(Storage_CreateStream_OlePres); 3812 SET_EXPECT(Storage_OpenStream_OlePres); 3813 SET_EXPECT(Storage_OpenStream_Ole); 3814 SET_EXPECT(Storage_DestroyElement); 3815 Storage_DestroyElement_limit = 50; 3816 Storage_SetClass_CLSID = &CLSID_NULL; 3817 trace("IPersistStorage_Save:\n"); 3818 hr = IPersistStorage_Save(stg, &Storage, FALSE); 3819 ok(hr == S_OK, "unexpected %#x\n", hr); 3820 CHECK_CALLED(Storage_CreateStream_OlePres); 3821 todo_wine 3822 CHECK_CALLED(Storage_OpenStream_OlePres); 3823 todo_wine 3824 CHECK_CALLED(Storage_OpenStream_Ole); 3825 todo_wine 3826 CHECK_CALLED(Storage_DestroyElement); 3827 3828 IStream_Release(olepres_stream); 3829 IStream_Release(contents_stream); 3830 3831 IPersistStorage_Release(stg); 3832 IOleCache2_Release(cache); 3833 } 3834 3835 #define MAX_STREAM 16 3836 3837 struct stream_def 3838 { 3839 const char *name; 3840 int cf; 3841 DVASPECT dvAspect; 3842 ADVF advf; 3843 const void *data; 3844 size_t data_size; 3845 }; 3846 3847 struct storage_def 3848 { 3849 const CLSID *clsid; 3850 int stream_count; 3851 struct stream_def stream[MAX_STREAM]; 3852 }; 3853 3854 static const struct storage_def stg_def_0 = 3855 { 3856 &CLSID_NULL, 1, 3857 {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }} 3858 }; 3859 static const struct storage_def stg_def_0_saved = 3860 { 3861 &CLSID_NULL, 0, {{ 0 }} 3862 }; 3863 static const struct storage_def stg_def_1 = 3864 { 3865 &CLSID_NULL, 2, 3866 {{ "Contents", -1, 0, 0, NULL, 0 }, 3867 { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} 3868 }; 3869 static const struct storage_def stg_def_1_saved = 3870 { 3871 &CLSID_NULL, 1, 3872 {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} 3873 }; 3874 static const struct storage_def stg_def_2 = 3875 { 3876 &CLSID_ManualResetEvent, 2, 3877 {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }, 3878 { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} 3879 }; 3880 static const struct storage_def stg_def_2_saved = 3881 { 3882 &CLSID_NULL, 1, 3883 {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} 3884 }; 3885 static const struct storage_def stg_def_3 = 3886 { 3887 &CLSID_NULL, 5, 3888 {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }, 3889 { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }, 3890 { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) }, 3891 { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) }, 3892 { "MyStream", -1, 0, 0, "Hello World!", 13 }} 3893 }; 3894 static const struct storage_def stg_def_3_saved = 3895 { 3896 &CLSID_NULL, 3, 3897 {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }, 3898 { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) }, 3899 { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) }} 3900 }; 3901 static const struct storage_def stg_def_4 = 3902 { 3903 &CLSID_Picture_EnhMetafile, 5, 3904 {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }, 3905 { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }, 3906 { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) }, 3907 { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) }, 3908 { "MyStream", -1, 0, 0, "Hello World!", 13 }} 3909 }; 3910 static const struct storage_def stg_def_4_saved = 3911 { 3912 &CLSID_NULL, 1, 3913 {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} 3914 }; 3915 static const struct storage_def stg_def_5 = 3916 { 3917 &CLSID_Picture_Dib, 5, 3918 {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }, 3919 { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) }, 3920 { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) }, 3921 { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }, 3922 { "MyStream", -1, 0, 0, "Hello World!", 13 }} 3923 }; 3924 static const struct storage_def stg_def_5_saved = 3925 { 3926 &CLSID_NULL, 1, 3927 {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} 3928 }; 3929 static const struct storage_def stg_def_6 = 3930 { 3931 &CLSID_Picture_Metafile, 5, 3932 {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }, 3933 { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, ADVF_PRIMEFIRST, mf_blank_bits, sizeof(mf_blank_bits) }, 3934 { "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }, 3935 { "\2OlePres002", CF_DIB, DVASPECT_CONTENT, ADVF_PRIMEFIRST, bmpimage, sizeof(bmpimage) }, 3936 { "MyStream", -1, 0, 0, "Hello World!", 13 }} 3937 }; 3938 static const struct storage_def stg_def_6_saved = 3939 { 3940 &CLSID_NULL, 1, 3941 {{ "\2OlePres000", 0, DVASPECT_ICON, ADVF_PRIMEFIRST | ADVF_ONLYONCE, NULL, 0 }} 3942 }; 3943 static const struct storage_def stg_def_7 = 3944 { 3945 &CLSID_Picture_Dib, 1, 3946 {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }} 3947 }; 3948 static const struct storage_def stg_def_7_saved = 3949 { 3950 &CLSID_NULL, 0, {{ 0 }} 3951 }; 3952 static const struct storage_def stg_def_8 = 3953 { 3954 &CLSID_Picture_Metafile, 1, 3955 {{ "Contents", -1, 0, 0, mf_blank_bits, sizeof(mf_blank_bits) }} 3956 }; 3957 static const struct storage_def stg_def_8_saved = 3958 { 3959 &CLSID_NULL, 0, {{ 0 }} 3960 }; 3961 static const struct storage_def stg_def_9 = 3962 { 3963 &CLSID_Picture_EnhMetafile, 1, 3964 {{ "Contents", -1, 0, 0, bmpimage, sizeof(bmpimage) }} 3965 }; 3966 static const struct storage_def stg_def_9_saved = 3967 { 3968 &CLSID_NULL, 0, {{ 0 }} 3969 }; 3970 3971 static int read_clipformat(IStream *stream) 3972 { 3973 HRESULT hr; 3974 ULONG bytes; 3975 int length, clipformat = -2; 3976 3977 hr = IStream_Read(stream, &length, sizeof(length), &bytes); 3978 if (hr != S_OK || bytes != sizeof(length)) 3979 return -2; 3980 if (length == 0) 3981 return 0; 3982 if (length == -1) 3983 { 3984 hr = IStream_Read(stream, &clipformat, sizeof(clipformat), &bytes); 3985 if (hr != S_OK || bytes != sizeof(clipformat)) 3986 return -2; 3987 } 3988 else 3989 ok(0, "unhandled clipformat length %d\n", length); 3990 3991 return clipformat; 3992 } 3993 3994 static void check_storage_contents(IStorage *stg, const struct storage_def *stg_def, 3995 int *enumerated_streams, int *matched_streams) 3996 { 3997 HRESULT hr; 3998 IEnumSTATSTG *enumstg; 3999 IStream *stream; 4000 STATSTG stat; 4001 int i, seen_stream[MAX_STREAM] = { 0 }; 4002 4003 if (winetest_debug > 1) 4004 trace("check_storage_contents:\n=============================================\n"); 4005 4006 *enumerated_streams = 0; 4007 *matched_streams = 0; 4008 4009 hr = IStorage_Stat(stg, &stat, STATFLAG_NONAME); 4010 ok(hr == S_OK, "unexpected %#x\n", hr); 4011 ok(IsEqualCLSID(stg_def->clsid, &stat.clsid), "expected %s, got %s\n", 4012 wine_dbgstr_guid(stg_def->clsid), wine_dbgstr_guid(&stat.clsid)); 4013 4014 hr = IStorage_EnumElements(stg, 0, NULL, 0, &enumstg); 4015 ok(hr == S_OK, "unexpected %#x\n", hr); 4016 4017 for (;;) 4018 { 4019 ULONG bytes; 4020 int clipformat = -1; 4021 PresentationDataHeader header; 4022 char name[32]; 4023 BYTE data[1024]; 4024 4025 memset(&header, 0, sizeof(header)); 4026 4027 hr = IEnumSTATSTG_Next(enumstg, 1, &stat, NULL); 4028 if(hr == S_FALSE) break; 4029 ok(hr == S_OK, "unexpected %#x\n", hr); 4030 4031 if (winetest_debug > 1) 4032 trace("name %s, type %u, size %d, clsid %s\n", 4033 wine_dbgstr_w(stat.pwcsName), stat.type, stat.cbSize.u.LowPart, wine_dbgstr_guid(&stat.clsid)); 4034 4035 ok(stat.type == STGTY_STREAM, "unexpected %#x\n", stat.type); 4036 4037 WideCharToMultiByte(CP_ACP, 0, stat.pwcsName, -1, name, sizeof(name), NULL, NULL); 4038 4039 hr = IStorage_OpenStream(stg, stat.pwcsName, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream); 4040 ok(hr == S_OK, "unexpected %#x\n", hr); 4041 4042 if (!memcmp(name, "\2OlePres", 8)) 4043 { 4044 ULONG header_size = sizeof(header); 4045 4046 clipformat = read_clipformat(stream); 4047 4048 if (clipformat == 0) /* view cache */ 4049 header_size = FIELD_OFFSET(PresentationDataHeader, unknown7); 4050 4051 hr = IStream_Read(stream, &header, header_size, &bytes); 4052 ok(hr == S_OK, "unexpected %#x\n", hr); 4053 ok(bytes == header_size, "read %u bytes, expected %u\n", bytes, header_size); 4054 4055 if (winetest_debug > 1) 4056 trace("header: tdSize %#x, dvAspect %#x, lindex %#x, advf %#x, unknown7 %#x, dwObjectExtentX %#x, dwObjectExtentY %#x, dwSize %#x\n", 4057 header.tdSize, header.dvAspect, header.lindex, header.advf, header.unknown7, 4058 header.dwObjectExtentX, header.dwObjectExtentY, header.dwSize); 4059 } 4060 4061 memset(data, 0, sizeof(data)); 4062 hr = IStream_Read(stream, data, sizeof(data), &bytes); 4063 ok(hr == S_OK, "unexpected %#x\n", hr); 4064 if (winetest_debug > 1) 4065 trace("stream data (%u bytes): %02x %02x %02x %02x\n", bytes, data[0], data[1], data[2], data[3]); 4066 4067 for (i = 0; i < stg_def->stream_count; i++) 4068 { 4069 if (seen_stream[i]) continue; 4070 4071 if (winetest_debug > 1) 4072 trace("%s/%s, %d/%d, %d/%d, %d/%d\n", 4073 stg_def->stream[i].name, name, 4074 stg_def->stream[i].cf, clipformat, 4075 stg_def->stream[i].dvAspect, header.dvAspect, 4076 stg_def->stream[i].advf, header.advf); 4077 4078 if (!strcmp(stg_def->stream[i].name, name) && 4079 stg_def->stream[i].cf == clipformat && 4080 stg_def->stream[i].dvAspect == header.dvAspect && 4081 stg_def->stream[i].advf == header.advf && 4082 stg_def->stream[i].data_size <= bytes && 4083 (!stg_def->stream[i].data_size || 4084 (!memcmp(stg_def->stream[i].data, data, min(stg_def->stream[i].data_size, bytes))))) 4085 { 4086 if (winetest_debug > 1) 4087 trace("stream %d matches def stream %d\n", *enumerated_streams, i); 4088 seen_stream[i] = 1; 4089 *matched_streams += 1; 4090 } 4091 } 4092 4093 CoTaskMemFree(stat.pwcsName); 4094 IStream_Release(stream); 4095 4096 *enumerated_streams += 1; 4097 } 4098 4099 IEnumSTATSTG_Release(enumstg); 4100 } 4101 4102 static HRESULT stgmedium_cmp(const STGMEDIUM *med1, STGMEDIUM *med2) 4103 { 4104 BYTE *data1, *data2; 4105 ULONG datasize1, datasize2; 4106 4107 if (med1->tymed != med2->tymed) 4108 return E_FAIL; 4109 4110 if (med1->tymed == TYMED_MFPICT) 4111 { 4112 METAFILEPICT *mfpict1 = GlobalLock(U(med1)->hMetaFilePict); 4113 METAFILEPICT *mfpict2 = GlobalLock(U(med2)->hMetaFilePict); 4114 4115 datasize1 = GetMetaFileBitsEx(mfpict1->hMF, 0, NULL); 4116 datasize2 = GetMetaFileBitsEx(mfpict2->hMF, 0, NULL); 4117 if (datasize1 == datasize2) 4118 { 4119 data1 = HeapAlloc(GetProcessHeap(), 0, datasize1); 4120 data2 = HeapAlloc(GetProcessHeap(), 0, datasize2); 4121 GetMetaFileBitsEx(mfpict1->hMF, datasize1, data1); 4122 GetMetaFileBitsEx(mfpict2->hMF, datasize2, data2); 4123 } 4124 else return E_FAIL; 4125 } 4126 else if (med1->tymed == TYMED_ENHMF) 4127 { 4128 datasize1 = GetEnhMetaFileBits(med1->hEnhMetaFile, 0, NULL); 4129 datasize2 = GetEnhMetaFileBits(med2->hEnhMetaFile, 0, NULL); 4130 if (datasize1 == datasize2) 4131 { 4132 data1 = HeapAlloc(GetProcessHeap(), 0, datasize1); 4133 data2 = HeapAlloc(GetProcessHeap(), 0, datasize2); 4134 GetEnhMetaFileBits(med1->hEnhMetaFile, datasize1, data1); 4135 GetEnhMetaFileBits(med2->hEnhMetaFile, datasize2, data2); 4136 } 4137 else return E_FAIL; 4138 } 4139 else if (med1->tymed == TYMED_HGLOBAL) 4140 { 4141 datasize1 = GlobalSize(med1->hGlobal); 4142 datasize2 = GlobalSize(med2->hGlobal); 4143 4144 if (datasize1 == datasize2) 4145 { 4146 data1 = GlobalLock(med1->hGlobal); 4147 data2 = GlobalLock(med2->hGlobal); 4148 } 4149 else 4150 return E_FAIL; 4151 } 4152 else 4153 return E_NOTIMPL; 4154 4155 if (memcmp(data1, data2, datasize1) != 0) 4156 return E_FAIL; 4157 4158 if (med1->tymed == TYMED_HGLOBAL) 4159 { 4160 GlobalUnlock(U(med1)->hGlobal); 4161 GlobalUnlock(U(med2)->hGlobal); 4162 } 4163 else if (med1->tymed == TYMED_MFPICT) 4164 { 4165 HeapFree(GetProcessHeap(), 0, data1); 4166 HeapFree(GetProcessHeap(), 0, data2); 4167 GlobalUnlock(U(med1)->hMetaFilePict); 4168 GlobalUnlock(U(med2)->hMetaFilePict); 4169 } 4170 else 4171 { 4172 HeapFree(GetProcessHeap(), 0, data1); 4173 HeapFree(GetProcessHeap(), 0, data2); 4174 } 4175 4176 return S_OK; 4177 } 4178 4179 static IStorage *create_storage_from_def(const struct storage_def *stg_def) 4180 { 4181 HRESULT hr; 4182 IStorage *stg; 4183 IStream *stm; 4184 int i; 4185 4186 hr = StgCreateDocfile(NULL, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &stg); 4187 ok(hr == S_OK, "unexpected %#x\n", hr); 4188 4189 hr = IStorage_SetClass(stg, stg_def->clsid); 4190 ok(hr == S_OK, "unexpected %#x\n", hr); 4191 4192 for (i = 0; i < stg_def->stream_count; i++) 4193 { 4194 WCHAR name[32]; 4195 4196 MultiByteToWideChar(CP_ACP, 0, stg_def->stream[i].name, -1, name, 32); 4197 hr = IStorage_CreateStream(stg, name, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stm); 4198 ok(hr == S_OK, "unexpected %#x\n", hr); 4199 4200 if (stg_def->stream[i].cf != -1) 4201 { 4202 int clipformat[2]; 4203 PresentationDataHeader hdr; 4204 4205 if (stg_def->stream[i].cf) 4206 { 4207 clipformat[0] = -1; 4208 clipformat[1] = stg_def->stream[i].cf; 4209 hr = IStream_Write(stm, clipformat, sizeof(clipformat), NULL); 4210 } 4211 else 4212 { 4213 clipformat[0] = 0; 4214 hr = IStream_Write(stm, &clipformat[0], sizeof(clipformat[0]), NULL); 4215 } 4216 ok(hr == S_OK, "unexpected %#x\n", hr); 4217 4218 hdr.tdSize = sizeof(hdr.tdSize); 4219 hdr.dvAspect = stg_def->stream[i].dvAspect; 4220 hdr.lindex = -1; 4221 hdr.advf = stg_def->stream[i].advf; 4222 hdr.unknown7 = 0; 4223 hdr.dwObjectExtentX = 0; 4224 hdr.dwObjectExtentY = 0; 4225 hdr.dwSize = stg_def->stream[i].data_size; 4226 hr = IStream_Write(stm, &hdr, sizeof(hdr), NULL); 4227 ok(hr == S_OK, "unexpected %#x\n", hr); 4228 } 4229 4230 if (stg_def->stream[i].data_size) 4231 { 4232 hr = IStream_Write(stm, stg_def->stream[i].data, stg_def->stream[i].data_size, NULL); 4233 ok(hr == S_OK, "unexpected %#x\n", hr); 4234 } 4235 4236 IStream_Release(stm); 4237 } 4238 4239 return stg; 4240 } 4241 4242 static const BYTE dib_inf[] = 4243 { 4244 0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 4245 0x00, 0x00, 0x36, 0x00, 0x00, 0x00 4246 }; 4247 4248 static const BYTE mf_rec[] = 4249 { 4250 0xd7, 0xcd, 0xc6, 0x9a, 0x00, 0x00, 0x00, 0x00, 4251 0x00, 0x00, 0x16, 0x00, 0x2d, 0x00, 0x40, 0x02, 4252 0x00, 0x00, 0x00, 0x00, 0x6a, 0x55 4253 }; 4254 4255 static void get_stgdef(struct storage_def *stg_def, CLIPFORMAT cf, STGMEDIUM *stg_med, int stm_idx) 4256 { 4257 BYTE *data; 4258 int data_size; 4259 METAFILEPICT *mfpict; 4260 HDC hdc; 4261 4262 switch (cf) 4263 { 4264 case CF_DIB: 4265 data_size = sizeof(dib); 4266 if (!strcmp(stg_def->stream[stm_idx].name, "CONTENTS")) 4267 { 4268 data_size += sizeof(dib_inf); 4269 data = HeapAlloc(GetProcessHeap(), 0, data_size); 4270 memcpy(data, dib_inf, sizeof(dib_inf)); 4271 memcpy(data + sizeof(dib_inf), dib, sizeof(dib)); 4272 } 4273 else 4274 { 4275 data = HeapAlloc(GetProcessHeap(), 0, data_size); 4276 memcpy(data, dib, sizeof(dib)); 4277 } 4278 stg_def->stream[stm_idx].data = data; 4279 stg_def->stream[stm_idx].data_size = data_size; 4280 break; 4281 case CF_METAFILEPICT: 4282 mfpict = GlobalLock(U(stg_med)->hMetaFilePict); 4283 data_size = GetMetaFileBitsEx(mfpict->hMF, 0, NULL); 4284 if (!strcmp(stg_def->stream[stm_idx].name, "CONTENTS")) 4285 { 4286 data = HeapAlloc(GetProcessHeap(), 0, data_size + sizeof(mf_rec)); 4287 memcpy(data, mf_rec, sizeof(mf_rec)); 4288 GetMetaFileBitsEx(mfpict->hMF, data_size, data + sizeof(mf_rec)); 4289 data_size += sizeof(mf_rec); 4290 } 4291 else 4292 { 4293 data = HeapAlloc(GetProcessHeap(), 0, data_size); 4294 GetMetaFileBitsEx(mfpict->hMF, data_size, data); 4295 } 4296 GlobalUnlock(U(stg_med)->hMetaFilePict); 4297 stg_def->stream[stm_idx].data_size = data_size; 4298 stg_def->stream[stm_idx].data = data; 4299 break; 4300 case CF_ENHMETAFILE: 4301 if (!strcmp(stg_def->stream[stm_idx].name, "CONTENTS")) 4302 { 4303 data_size = GetEnhMetaFileBits(U(stg_med)->hEnhMetaFile, 0, NULL); 4304 data = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD) + sizeof(ENHMETAHEADER) + data_size); 4305 *((DWORD *)data) = sizeof(ENHMETAHEADER); 4306 GetEnhMetaFileBits(U(stg_med)->hEnhMetaFile, data_size, data + sizeof(DWORD) + sizeof(ENHMETAHEADER)); 4307 memcpy(data + sizeof(DWORD), data + sizeof(DWORD) + sizeof(ENHMETAHEADER), sizeof(ENHMETAHEADER)); 4308 data_size += sizeof(DWORD) + sizeof(ENHMETAHEADER); 4309 } 4310 else 4311 { 4312 hdc = GetDC(NULL); 4313 data_size = GetWinMetaFileBits(U(stg_med)->hEnhMetaFile, 0, NULL, MM_ANISOTROPIC, hdc); 4314 data = HeapAlloc(GetProcessHeap(), 0, data_size); 4315 GetWinMetaFileBits(U(stg_med)->hEnhMetaFile, data_size, data, MM_ANISOTROPIC, hdc); 4316 ReleaseDC(NULL, hdc); 4317 } 4318 stg_def->stream[stm_idx].data_size = data_size; 4319 stg_def->stream[stm_idx].data = data; 4320 break; 4321 } 4322 } 4323 4324 static void get_stgmedium(CLIPFORMAT cfFormat, STGMEDIUM *stgmedium) 4325 { 4326 switch (cfFormat) 4327 { 4328 case CF_DIB: 4329 create_dib(stgmedium); 4330 break; 4331 case CF_METAFILEPICT: 4332 create_mfpict(stgmedium); 4333 break; 4334 case CF_ENHMETAFILE: 4335 create_emf(stgmedium); 4336 break; 4337 default: 4338 ok(0, "cf %x not implemented\n", cfFormat); 4339 } 4340 } 4341 4342 #define MAX_FMTS 5 4343 static void test_data_cache_save_data(void) 4344 { 4345 HRESULT hr; 4346 STGMEDIUM stgmed; 4347 ILockBytes *ilb; 4348 IStorage *doc; 4349 IOleCache2 *cache; 4350 IPersistStorage *persist; 4351 IDataObject *odata; 4352 int enumerated_streams, matched_streams, i; 4353 DWORD dummy; 4354 STGMEDIUM stgmeds[MAX_FMTS]; 4355 struct tests_data_cache 4356 { 4357 FORMATETC fmts[MAX_FMTS]; 4358 int num_fmts, num_set; 4359 const CLSID *clsid; 4360 struct storage_def stg_def; 4361 }; 4362 4363 static struct tests_data_cache *pdata, data[] = 4364 { 4365 { 4366 { 4367 { CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 4368 { CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 4369 { CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 4370 { 0, 0, DVASPECT_DOCPRINT, -1, TYMED_HGLOBAL }, 4371 }, 4372 4, 3, &CLSID_WineTest, 4373 { 4374 &CLSID_WineTestOld, 4, { { "\2OlePres000", CF_DIB, DVASPECT_CONTENT, 0, NULL, 0 }, 4375 { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, 0, NULL, 0 }, 4376 { "\2OlePres002", CF_ENHMETAFILE, DVASPECT_CONTENT, 0, NULL, 0 }, 4377 { "\2OlePres003", 0, DVASPECT_DOCPRINT, 0, NULL, 0 } } 4378 } 4379 }, 4380 /* without setting data */ 4381 { 4382 { 4383 { CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 4384 { CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 4385 { CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 4386 }, 4387 3, 0, &CLSID_WineTest, 4388 { 4389 &CLSID_WineTestOld, 3, { { "\2OlePres000", CF_DIB, DVASPECT_CONTENT, 0, NULL, 0 }, 4390 { "\2OlePres001", CF_METAFILEPICT, DVASPECT_CONTENT, 0, NULL, 0 }, 4391 { "\2OlePres002", CF_ENHMETAFILE, DVASPECT_CONTENT, 0, NULL, 0 } } 4392 } 4393 }, 4394 /* static picture clsids */ 4395 { 4396 { 4397 { CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 4398 }, 4399 1, 1, &CLSID_Picture_Dib, 4400 { 4401 &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } 4402 } 4403 }, 4404 { 4405 { 4406 { CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 4407 }, 4408 1, 1, &CLSID_Picture_Metafile, 4409 { 4410 &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } 4411 } 4412 }, 4413 { 4414 { 4415 { CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 4416 }, 4417 1, 1, &CLSID_Picture_EnhMetafile, 4418 { 4419 &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } 4420 } 4421 }, 4422 /* static picture clsids without setting any data */ 4423 { 4424 { 4425 { CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 4426 }, 4427 1, 0, &CLSID_Picture_Dib, 4428 { 4429 &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } 4430 } 4431 }, 4432 { 4433 { 4434 { CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT }, 4435 }, 4436 1, 0, &CLSID_Picture_Metafile, 4437 { 4438 &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } 4439 } 4440 }, 4441 { 4442 { 4443 { CF_ENHMETAFILE, 0, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 4444 }, 4445 1, 0, &CLSID_Picture_EnhMetafile, 4446 { 4447 &CLSID_WineTestOld, 1, { { "CONTENTS", -1, 0, 0, NULL, 0 } } 4448 } 4449 }, 4450 { 4451 { 4452 { 0 } 4453 } 4454 } 4455 }; 4456 4457 /* test _Save after caching directly through _Cache + _SetData */ 4458 for (pdata = data; pdata->clsid != NULL; pdata++) 4459 { 4460 hr = CreateDataCache(NULL, pdata->clsid, &IID_IOleCache2, (void **)&cache); 4461 ok(hr == S_OK, "unexpected %#x\n", hr); 4462 4463 for (i = 0; i < pdata->num_fmts; i++) 4464 { 4465 hr = IOleCache2_Cache(cache, &pdata->fmts[i], 0, &dummy); 4466 ok(SUCCEEDED(hr), "unexpected %#x\n", hr); 4467 if (i < pdata->num_set) 4468 { 4469 get_stgmedium(pdata->fmts[i].cfFormat, &stgmeds[i]); 4470 get_stgdef(&pdata->stg_def, pdata->fmts[i].cfFormat, &stgmeds[i], i); 4471 hr = IOleCache2_SetData(cache, &pdata->fmts[i], &stgmeds[i], FALSE); 4472 ok(hr == S_OK, "unexpected %#x\n", hr); 4473 } 4474 } 4475 4476 /* create Storage in memory where we'll save cache */ 4477 hr = CreateILockBytesOnHGlobal(0, TRUE, &ilb); 4478 ok(hr == S_OK, "unexpected %#x\n", hr); 4479 hr = StgCreateDocfileOnILockBytes(ilb, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, &doc); 4480 ok(hr == S_OK, "unexpected %#x\n", hr); 4481 ILockBytes_Release(ilb); 4482 hr = IStorage_SetClass(doc, &CLSID_WineTestOld); 4483 ok(hr == S_OK, "unexpected %#x\n", hr); 4484 4485 hr = IOleCache2_QueryInterface(cache, &IID_IPersistStorage, (void **)&persist); 4486 ok(hr == S_OK, "unexpected %#x\n", hr); 4487 4488 /* cache entries are dirty. test saving them to stg */ 4489 trace("IPersistStorage_Save:\n"); 4490 hr = IPersistStorage_Save(persist, doc, FALSE); 4491 ok(hr == S_OK, "unexpected %#x\n", hr); 4492 4493 hr = IPersistStorage_IsDirty(persist); 4494 ok(hr == S_OK, "unexpected %#x\n", hr); 4495 4496 check_storage_contents(doc, &pdata->stg_def, &enumerated_streams, &matched_streams); 4497 ok(enumerated_streams == matched_streams, "enumerated %d != matched %d\n", 4498 enumerated_streams, matched_streams); 4499 ok(enumerated_streams == pdata->stg_def.stream_count, "created %d != def streams %d\n", 4500 enumerated_streams, pdata->stg_def.stream_count); 4501 4502 IPersistStorage_Release(persist); 4503 IOleCache2_Release(cache); 4504 4505 /* now test _Load/_GetData using the storage we used for _Save */ 4506 hr = CreateDataCache(NULL, pdata->clsid, &IID_IOleCache2, (void **)&cache); 4507 ok(hr == S_OK, "unexpected %#x\n", hr); 4508 hr = IOleCache2_QueryInterface(cache, &IID_IPersistStorage, (void **)&persist); 4509 ok(hr == S_OK, "unexpected %#x\n", hr); 4510 4511 hr = IStorage_SetClass(doc, pdata->clsid); 4512 ok(hr == S_OK, "unexpected %#x\n", hr); 4513 trace("IPersistStorage_Load\n"); 4514 hr = IPersistStorage_Load(persist, doc); 4515 ok(hr == S_OK, "unexpected %#x\n", hr); 4516 4517 hr = IOleCache2_QueryInterface(cache, &IID_IDataObject, (void **)&odata); 4518 ok(hr == S_OK, "unexpected %#x\n", hr); 4519 for (i = 0; i < pdata->num_set; i++) 4520 { 4521 hr = IDataObject_GetData(odata, &pdata->fmts[i], &stgmed); 4522 ok(hr == S_OK, "unexpected %#x\n", hr); 4523 4524 hr = stgmedium_cmp(&stgmeds[i], &stgmed); 4525 ok(hr == S_OK, "unexpected %#x\n", hr); 4526 ReleaseStgMedium(&stgmed); 4527 ReleaseStgMedium(&stgmeds[i]); 4528 } 4529 4530 IDataObject_Release(odata); 4531 IPersistStorage_Release(persist); 4532 IStorage_Release(doc); 4533 IOleCache2_Release(cache); 4534 for (i = 0; i < pdata->num_set; i++) 4535 HeapFree(GetProcessHeap(), 0, (void *)pdata->stg_def.stream[i].data); 4536 4537 } 4538 } 4539 4540 static void test_data_cache_contents(void) 4541 { 4542 HRESULT hr; 4543 IStorage *doc1, *doc2; 4544 IOleCache2 *cache; 4545 IPersistStorage *stg; 4546 int i, enumerated_streams, matched_streams; 4547 static const struct 4548 { 4549 const struct storage_def *in; 4550 const struct storage_def *out; 4551 } test_data[] = 4552 { 4553 { &stg_def_0, &stg_def_0_saved }, 4554 { &stg_def_1, &stg_def_1_saved }, 4555 { &stg_def_2, &stg_def_2_saved }, 4556 { &stg_def_3, &stg_def_3_saved }, 4557 { &stg_def_4, &stg_def_4_saved }, 4558 { &stg_def_5, &stg_def_5_saved }, 4559 { &stg_def_6, &stg_def_6_saved }, 4560 { &stg_def_7, &stg_def_7_saved }, 4561 { &stg_def_8, &stg_def_8_saved }, 4562 { &stg_def_9, &stg_def_9_saved }, 4563 }; 4564 4565 for (i = 0; i < ARRAY_SIZE(test_data); i++) 4566 { 4567 if (winetest_debug > 1) 4568 trace("start testing storage def %d\n", i); 4569 4570 doc1 = create_storage_from_def(test_data[i].in); 4571 if (!doc1) continue; 4572 4573 enumerated_streams = matched_streams = -1; 4574 check_storage_contents(doc1, test_data[i].in, &enumerated_streams, &matched_streams); 4575 ok(enumerated_streams == matched_streams, "%d in: enumerated %d != matched %d\n", i, 4576 enumerated_streams, matched_streams); 4577 ok(enumerated_streams == test_data[i].in->stream_count, "%d: created %d != def streams %d\n", i, 4578 enumerated_streams, test_data[i].in->stream_count); 4579 4580 hr = CreateDataCache(NULL, &CLSID_NULL, &IID_IUnknown, (void **)&cache); 4581 ok(hr == S_OK, "unexpected %#x\n", hr); 4582 hr = IOleCache2_QueryInterface(cache, &IID_IPersistStorage, (void **)&stg); 4583 ok(hr == S_OK, "unexpected %#x\n", hr); 4584 hr = IPersistStorage_Load(stg, doc1); 4585 ok(hr == S_OK, "unexpected %#x\n", hr); 4586 4587 IStorage_Release(doc1); 4588 4589 hr = StgCreateDocfile(NULL, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &doc2); 4590 ok(hr == S_OK, "unexpected %#x\n", hr); 4591 4592 hr = IPersistStorage_IsDirty(stg); 4593 ok(hr == S_FALSE, "%d: unexpected %#x\n", i, hr); 4594 4595 hr = IPersistStorage_Save(stg, doc2, FALSE); 4596 ok(hr == S_OK, "unexpected %#x\n", hr); 4597 4598 IPersistStorage_Release(stg); 4599 4600 enumerated_streams = matched_streams = -1; 4601 check_storage_contents(doc2, test_data[i].out, &enumerated_streams, &matched_streams); 4602 todo_wine_if(!(test_data[i].in == &stg_def_0 || test_data[i].in == &stg_def_1 || test_data[i].in == &stg_def_2)) 4603 ok(enumerated_streams == matched_streams, "%d out: enumerated %d != matched %d\n", i, 4604 enumerated_streams, matched_streams); 4605 todo_wine_if(!(test_data[i].in == &stg_def_0 || test_data[i].in == &stg_def_4 || test_data[i].in == &stg_def_5 4606 || test_data[i].in == &stg_def_6)) 4607 ok(enumerated_streams == test_data[i].out->stream_count, "%d: saved streams %d != def streams %d\n", i, 4608 enumerated_streams, test_data[i].out->stream_count); 4609 4610 IStorage_Release(doc2); 4611 4612 if (winetest_debug > 1) 4613 trace("done testing storage def %d\n", i); 4614 } 4615 } 4616 4617 static void test_OleCreateStaticFromData(void) 4618 { 4619 HRESULT hr; 4620 IOleObject *ole_obj = NULL; 4621 IStorage *storage; 4622 ILockBytes *ilb; 4623 IPersist *persist; 4624 CLSID clsid; 4625 STATSTG statstg; 4626 int enumerated_streams, matched_streams; 4627 STGMEDIUM stgmed; 4628 static FORMATETC dib_fmt[] = 4629 { 4630 { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 4631 { 0 } 4632 }; 4633 static FORMATETC emf_fmt[] = 4634 { 4635 { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF }, 4636 { 0 } 4637 }; 4638 static FORMATETC text_fmt[] = 4639 { 4640 { CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }, 4641 { 0 } 4642 }; 4643 static const struct expected_method methods_create_from_dib[] = 4644 { 4645 { "DataObject_EnumFormatEtc", TEST_TODO }, 4646 { "DataObject_GetDataHere", 0 }, 4647 { "DataObject_QueryGetData", 0, { CF_METAFILEPICT, NULL, DVASPECT_CONTENT, -1, TYMED_ISTORAGE } }, 4648 { NULL } 4649 }; 4650 static const struct expected_method methods_createstatic_from_dib[] = 4651 { 4652 { "DataObject_GetData", 0, { CF_DIB, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, 4653 { NULL } 4654 }; 4655 static const struct expected_method methods_createstatic_from_emf[] = 4656 { 4657 { "DataObject_GetData", 0, { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF } }, 4658 { NULL } 4659 }; 4660 static const struct expected_method methods_createstatic_from_text[] = 4661 { 4662 { "DataObject_GetData", 0, { CF_TEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL } }, 4663 { NULL } 4664 }; 4665 static struct storage_def stg_def_dib = 4666 { 4667 &CLSID_Picture_Dib, 3, 4668 {{ "\1Ole", -1, 0, 0, NULL, 0 }, 4669 { "\1CompObj", -1, 0, 0, NULL, 0 }, 4670 { "CONTENTS", -1, 0, 0, NULL, 0 }} 4671 }; 4672 static struct storage_def stg_def_emf = 4673 { 4674 &CLSID_Picture_EnhMetafile, 3, 4675 {{ "\1Ole", -1, 0, 0, NULL, 0 }, 4676 { "\1CompObj", -1, 0, 0, NULL, 0 }, 4677 { "CONTENTS", -1, 0, 0, NULL, 0 }} 4678 }; 4679 4680 4681 hr = CreateILockBytesOnHGlobal(NULL, TRUE, &ilb); 4682 ok(hr == S_OK, "CreateILockBytesOnHGlobal failed: 0x%08x.\n", hr); 4683 hr = StgCreateDocfileOnILockBytes(ilb, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 4684 0, &storage); 4685 ok(hr == S_OK, "StgCreateDocfileOnILockBytes failed: 0x%08x.\n", hr); 4686 ILockBytes_Release(ilb); 4687 4688 hr = OleCreateStaticFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT, 4689 dib_fmt, NULL, NULL, (void **)&ole_obj); 4690 ok(hr == E_INVALIDARG, "OleCreateStaticFromData should fail: 0x%08x.\n", hr); 4691 4692 hr = OleCreateStaticFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT, 4693 dib_fmt, NULL, storage, NULL); 4694 ok(hr == E_INVALIDARG, "OleCreateStaticFromData should fail: 0x%08x.\n", hr); 4695 4696 /* CF_DIB */ 4697 g_dataobject_fmts = dib_fmt; 4698 expected_method_list = methods_createstatic_from_dib; 4699 hr = OleCreateStaticFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT, 4700 dib_fmt, NULL, storage, (void **)&ole_obj); 4701 ok(hr == S_OK, "OleCreateStaticFromData failed: 0x%08x.\n", hr); 4702 hr = IOleObject_QueryInterface(ole_obj, &IID_IPersist, (void **)&persist); 4703 ok(hr == S_OK, "IOleObject_QueryInterface failed: 0x%08x.\n", hr); 4704 hr = IPersist_GetClassID(persist, &clsid); 4705 ok(hr == S_OK, "IPersist_GetClassID failed: 0x%08x.\n", hr); 4706 ok(IsEqualCLSID(&clsid, &CLSID_Picture_Dib), "Got wrong clsid: %s, expected: %s.\n", 4707 wine_dbgstr_guid(&clsid), wine_dbgstr_guid(&CLSID_Picture_Dib)); 4708 hr = IStorage_Stat(storage, &statstg, STATFLAG_NONAME); 4709 ok_ole_success(hr, "IStorage_Stat"); 4710 ok(IsEqualCLSID(&CLSID_Picture_Dib, &statstg.clsid), "Wrong CLSID in storage.\n"); 4711 enumerated_streams = matched_streams = -1; 4712 get_stgmedium(CF_DIB, &stgmed); 4713 get_stgdef(&stg_def_dib, CF_DIB, &stgmed, 2); 4714 check_storage_contents(storage, &stg_def_dib, &enumerated_streams, &matched_streams); 4715 ok(enumerated_streams == matched_streams, "enumerated %d != matched %d\n", 4716 enumerated_streams, matched_streams); 4717 ok(enumerated_streams == stg_def_dib.stream_count, "created %d != def streams %d\n", 4718 enumerated_streams, stg_def_dib.stream_count); 4719 ReleaseStgMedium(&stgmed); 4720 IPersist_Release(persist); 4721 IStorage_Release(storage); 4722 IOleObject_Release(ole_obj); 4723 4724 /* CF_ENHMETAFILE */ 4725 hr = CreateILockBytesOnHGlobal(NULL, TRUE, &ilb); 4726 ok(hr == S_OK, "CreateILockBytesOnHGlobal failed: 0x%08x.\n", hr); 4727 hr = StgCreateDocfileOnILockBytes(ilb, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 4728 0, &storage); 4729 ok(hr == S_OK, "StgCreateDocfileOnILockBytes failed: 0x%08x.\n", hr); 4730 ILockBytes_Release(ilb); 4731 g_dataobject_fmts = emf_fmt; 4732 expected_method_list = methods_createstatic_from_emf; 4733 hr = OleCreateStaticFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT, 4734 emf_fmt, NULL, storage, (void **)&ole_obj); 4735 ok(hr == S_OK, "OleCreateStaticFromData failed: 0x%08x.\n", hr); 4736 hr = IOleObject_QueryInterface(ole_obj, &IID_IPersist, (void **)&persist); 4737 ok(hr == S_OK, "IOleObject_QueryInterface failed: 0x%08x.\n", hr); 4738 hr = IPersist_GetClassID(persist, &clsid); 4739 ok(hr == S_OK, "IPersist_GetClassID failed: 0x%08x.\n", hr); 4740 ok(IsEqualCLSID(&clsid, &CLSID_Picture_EnhMetafile), "Got wrong clsid: %s, expected: %s.\n", 4741 wine_dbgstr_guid(&clsid), wine_dbgstr_guid(&CLSID_Picture_EnhMetafile)); 4742 hr = IStorage_Stat(storage, &statstg, STATFLAG_NONAME); 4743 ok_ole_success(hr, "IStorage_Stat"); 4744 ok(IsEqualCLSID(&CLSID_Picture_EnhMetafile, &statstg.clsid), "Wrong CLSID in storage.\n"); 4745 enumerated_streams = matched_streams = -1; 4746 get_stgmedium(CF_ENHMETAFILE, &stgmed); 4747 get_stgdef(&stg_def_emf, CF_ENHMETAFILE, &stgmed, 2); 4748 check_storage_contents(storage, &stg_def_emf, &enumerated_streams, &matched_streams); 4749 ok(enumerated_streams == matched_streams, "enumerated %d != matched %d\n", 4750 enumerated_streams, matched_streams); 4751 ok(enumerated_streams == stg_def_emf.stream_count, "created %d != def streams %d\n", 4752 enumerated_streams, stg_def_emf.stream_count); 4753 ReleaseStgMedium(&stgmed); 4754 IPersist_Release(persist); 4755 IStorage_Release(storage); 4756 IOleObject_Release(ole_obj); 4757 4758 /* CF_TEXT */ 4759 hr = CreateILockBytesOnHGlobal(NULL, TRUE, &ilb); 4760 ok(hr == S_OK, "CreateILockBytesOnHGlobal failed: 0x%08x.\n", hr); 4761 hr = StgCreateDocfileOnILockBytes(ilb, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 4762 0, &storage); 4763 ok(hr == S_OK, "StgCreateDocfileOnILockBytes failed: 0x%08x.\n", hr); 4764 ILockBytes_Release(ilb); 4765 g_dataobject_fmts = text_fmt; 4766 expected_method_list = methods_createstatic_from_text; 4767 hr = OleCreateStaticFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT, 4768 text_fmt, NULL, storage, (void **)&ole_obj); 4769 ok(hr == DV_E_CLIPFORMAT, "OleCreateStaticFromData should fail: 0x%08x.\n", hr); 4770 IStorage_Release(storage); 4771 4772 hr = CreateILockBytesOnHGlobal(NULL, TRUE, &ilb); 4773 ok(hr == S_OK, "CreateILockBytesOnHGlobal failed: 0x%08x.\n", hr); 4774 hr = StgCreateDocfileOnILockBytes(ilb, STGM_SHARE_EXCLUSIVE | STGM_CREATE | STGM_READWRITE, 4775 0, &storage); 4776 ok(hr == S_OK, "StgCreateDocfileOnILockBytes failed: 0x%08x.\n", hr); 4777 ILockBytes_Release(ilb); 4778 g_dataobject_fmts = dib_fmt; 4779 expected_method_list = methods_create_from_dib; 4780 hr = OleCreateFromData(&DataObject, &IID_IOleObject, OLERENDER_FORMAT, dib_fmt, NULL, 4781 storage, (void **)&ole_obj); 4782 todo_wine ok(hr == DV_E_FORMATETC, "OleCreateFromData should failed: 0x%08x.\n", hr); 4783 IStorage_Release(storage); 4784 } 4785 4786 START_TEST(ole2) 4787 { 4788 DWORD dwRegister; 4789 IStorage *pStorage; 4790 STATSTG statstg; 4791 HRESULT hr; 4792 4793 cf_test_1 = RegisterClipboardFormatA("cf_winetest_1"); 4794 cf_test_2 = RegisterClipboardFormatA("cf_winetest_2"); 4795 cf_test_3 = RegisterClipboardFormatA("cf_winetest_3"); 4796 4797 CoInitialize(NULL); 4798 4799 hr = CoRegisterClassObject(&CLSID_Equation3, (IUnknown *)&OleObjectCF, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegister); 4800 ok_ole_success(hr, "CoRegisterClassObject"); 4801 4802 hr = StgCreateDocfile(NULL, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE | STGM_DELETEONRELEASE, 0, &pStorage); 4803 ok_ole_success(hr, "StgCreateDocfile"); 4804 4805 test_OleCreate(pStorage); 4806 4807 hr = IStorage_Stat(pStorage, &statstg, STATFLAG_NONAME); 4808 ok_ole_success(hr, "IStorage_Stat"); 4809 ok(IsEqualCLSID(&CLSID_Equation3, &statstg.clsid), "Wrong CLSID in storage\n"); 4810 4811 test_OleLoad(pStorage); 4812 4813 IStorage_Release(pStorage); 4814 4815 hr = CoRevokeClassObject(dwRegister); 4816 ok_ole_success(hr, "CoRevokeClassObject"); 4817 4818 Storage_SetClass_CLSID = &CLSID_WineTest; 4819 4820 test_data_cache(); 4821 test_data_cache_dib_contents_stream( 0 ); 4822 test_data_cache_dib_contents_stream( 1 ); 4823 test_data_cache_cache(); 4824 test_data_cache_init(); 4825 test_data_cache_initnew(); 4826 test_data_cache_updatecache(); 4827 test_default_handler(); 4828 test_runnable(); 4829 test_OleRun(); 4830 test_OleLockRunning(); 4831 test_OleDraw(); 4832 test_OleDoAutoConvert(); 4833 test_data_cache_save(); 4834 test_data_cache_save_data(); 4835 test_data_cache_contents(); 4836 test_OleCreateStaticFromData(); 4837 4838 CoUninitialize(); 4839 } 4840