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