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