1 /* 2 * OLE 2 default object handler 3 * 4 * Copyright 1999 Francis Beaudet 5 * Copyright 2000 Abey George 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 * NOTES: 22 * The OLE2 default object handler supports a whole whack of 23 * interfaces including: 24 * IOleObject, IDataObject, IPersistStorage, IViewObject2, 25 * IRunnableObject, IOleCache2, IOleCacheControl and much more. 26 * 27 * All the implementation details are taken from: Inside OLE 28 * second edition by Kraig Brockschmidt, 29 * 30 * TODO 31 * - This implementation of the default handler does not launch the 32 * server in the DoVerb, Update, GetData, GetDataHere and Run 33 * methods. When it is fixed to do so, all the methods will have 34 * to be revisited to allow delegating to the running object 35 * 36 * - All methods in the class that use the class ID should be 37 * aware that it is possible for a class to be treated as 38 * another one and go into emulation mode. Nothing has been 39 * done in this area. 40 * 41 * - Some functions still return E_NOTIMPL they have to be 42 * implemented. Most of those are related to the running of the 43 * actual server. 44 * 45 * - All the methods related to notification and advise sinks are 46 * in place but no notifications are sent to the sinks yet. 47 */ 48 #include <assert.h> 49 #include <stdarg.h> 50 #include <string.h> 51 52 #define COBJMACROS 53 54 #include "windef.h" 55 #include "winbase.h" 56 #include "winuser.h" 57 #include "winerror.h" 58 #include "ole2.h" 59 60 #include "compobj_private.h" 61 #include "storage32.h" 62 63 #include "wine/debug.h" 64 65 WINE_DEFAULT_DEBUG_CHANNEL(ole); 66 67 enum storage_state 68 { 69 storage_state_uninitialised, 70 storage_state_initialised, 71 storage_state_loaded 72 }; 73 74 enum object_state 75 { 76 object_state_not_running, 77 object_state_running, 78 object_state_deferred_close 79 }; 80 81 /**************************************************************************** 82 * DefaultHandler 83 * 84 */ 85 struct DefaultHandler 86 { 87 IOleObject IOleObject_iface; 88 IUnknown IUnknown_iface; 89 IDataObject IDataObject_iface; 90 IRunnableObject IRunnableObject_iface; 91 IAdviseSink IAdviseSink_iface; 92 IPersistStorage IPersistStorage_iface; 93 94 /* Reference count of this object */ 95 LONG ref; 96 97 /* IUnknown implementation of the outer object. */ 98 IUnknown* outerUnknown; 99 100 /* Class Id that this handler object represents. */ 101 CLSID clsid; 102 103 /* IUnknown implementation of the datacache. */ 104 IUnknown* dataCache; 105 /* IPersistStorage implementation of the datacache. */ 106 IPersistStorage* dataCache_PersistStg; 107 108 /* Client site for the embedded object. */ 109 IOleClientSite* clientSite; 110 111 /* 112 * The IOleAdviseHolder maintains the connections 113 * on behalf of the default handler. 114 */ 115 IOleAdviseHolder* oleAdviseHolder; 116 117 /* 118 * The IDataAdviseHolder maintains the data 119 * connections on behalf of the default handler. 120 */ 121 IDataAdviseHolder* dataAdviseHolder; 122 123 /* Name of the container and object contained */ 124 LPWSTR containerApp; 125 LPWSTR containerObj; 126 127 /* IOleObject delegate */ 128 IOleObject *pOleDelegate; 129 /* IPersistStorage delegate */ 130 IPersistStorage *pPSDelegate; 131 /* IDataObject delegate */ 132 IDataObject *pDataDelegate; 133 enum object_state object_state; 134 ULONG in_call; 135 136 /* connection cookie for the advise on the delegate OLE object */ 137 DWORD dwAdvConn; 138 139 /* storage passed to Load or InitNew */ 140 IStorage *storage; 141 enum storage_state storage_state; 142 143 /* optional class factory for object */ 144 IClassFactory *pCFObject; 145 /* TRUE if acting as an inproc server instead of an inproc handler */ 146 BOOL inproc_server; 147 }; 148 149 typedef struct DefaultHandler DefaultHandler; 150 151 static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface ) 152 { 153 return CONTAINING_RECORD(iface, DefaultHandler, IOleObject_iface); 154 } 155 156 static inline DefaultHandler *impl_from_IUnknown( IUnknown *iface ) 157 { 158 return CONTAINING_RECORD(iface, DefaultHandler, IUnknown_iface); 159 } 160 161 static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface ) 162 { 163 return CONTAINING_RECORD(iface, DefaultHandler, IDataObject_iface); 164 } 165 166 static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface ) 167 { 168 return CONTAINING_RECORD(iface, DefaultHandler, IRunnableObject_iface); 169 } 170 171 static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface ) 172 { 173 return CONTAINING_RECORD(iface, DefaultHandler, IAdviseSink_iface); 174 } 175 176 static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface ) 177 { 178 return CONTAINING_RECORD(iface, DefaultHandler, IPersistStorage_iface); 179 } 180 181 static void DefaultHandler_Destroy(DefaultHandler* This); 182 183 static inline BOOL object_is_running(DefaultHandler *This) 184 { 185 return IRunnableObject_IsRunning(&This->IRunnableObject_iface); 186 } 187 188 static void DefaultHandler_Stop(DefaultHandler *This); 189 190 static inline void start_object_call(DefaultHandler *This) 191 { 192 This->in_call++; 193 } 194 195 static inline void end_object_call(DefaultHandler *This) 196 { 197 This->in_call--; 198 if (This->in_call == 0 && This->object_state == object_state_deferred_close) 199 DefaultHandler_Stop( This ); 200 } 201 202 /********************************************************* 203 * Method implementation for the non delegating IUnknown 204 * part of the DefaultHandler class. 205 */ 206 207 /************************************************************************ 208 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown) 209 * 210 * See Windows documentation for more details on IUnknown methods. 211 * 212 * This version of QueryInterface will not delegate its implementation 213 * to the outer unknown. 214 */ 215 static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface( 216 IUnknown* iface, 217 REFIID riid, 218 void** ppvObject) 219 { 220 DefaultHandler *This = impl_from_IUnknown(iface); 221 222 if (!ppvObject) 223 return E_INVALIDARG; 224 225 *ppvObject = NULL; 226 227 if (IsEqualIID(&IID_IUnknown, riid)) 228 *ppvObject = iface; 229 else if (IsEqualIID(&IID_IOleObject, riid)) 230 *ppvObject = &This->IOleObject_iface; 231 else if (IsEqualIID(&IID_IDataObject, riid)) 232 *ppvObject = &This->IDataObject_iface; 233 else if (IsEqualIID(&IID_IRunnableObject, riid)) 234 *ppvObject = &This->IRunnableObject_iface; 235 else if (IsEqualIID(&IID_IPersist, riid) || 236 IsEqualIID(&IID_IPersistStorage, riid)) 237 *ppvObject = &This->IPersistStorage_iface; 238 else if (IsEqualIID(&IID_IViewObject, riid) || 239 IsEqualIID(&IID_IViewObject2, riid) || 240 IsEqualIID(&IID_IOleCache, riid) || 241 IsEqualIID(&IID_IOleCache2, riid)) 242 { 243 HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject); 244 if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid)); 245 return hr; 246 } 247 else if (This->inproc_server && This->pOleDelegate) 248 { 249 return IOleObject_QueryInterface(This->pOleDelegate, riid, ppvObject); 250 } 251 252 /* Check that we obtained an interface. */ 253 if (*ppvObject == NULL) 254 { 255 WARN( "() : asking for unsupported interface %s\n", debugstr_guid(riid)); 256 return E_NOINTERFACE; 257 } 258 259 /* 260 * Query Interface always increases the reference count by one when it is 261 * successful. 262 */ 263 IUnknown_AddRef((IUnknown*)*ppvObject); 264 265 return S_OK; 266 } 267 268 /************************************************************************ 269 * DefaultHandler_NDIUnknown_AddRef (IUnknown) 270 * 271 * See Windows documentation for more details on IUnknown methods. 272 * 273 * This version of QueryInterface will not delegate its implementation 274 * to the outer unknown. 275 */ 276 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef( 277 IUnknown* iface) 278 { 279 DefaultHandler *This = impl_from_IUnknown(iface); 280 return InterlockedIncrement(&This->ref); 281 } 282 283 /************************************************************************ 284 * DefaultHandler_NDIUnknown_Release (IUnknown) 285 * 286 * See Windows documentation for more details on IUnknown methods. 287 * 288 * This version of QueryInterface will not delegate its implementation 289 * to the outer unknown. 290 */ 291 static ULONG WINAPI DefaultHandler_NDIUnknown_Release( 292 IUnknown* iface) 293 { 294 DefaultHandler *This = impl_from_IUnknown(iface); 295 ULONG ref; 296 297 ref = InterlockedDecrement(&This->ref); 298 299 if (!ref) DefaultHandler_Destroy(This); 300 301 return ref; 302 } 303 304 /********************************************************* 305 * Methods implementation for the IOleObject part of 306 * the DefaultHandler class. 307 */ 308 309 /************************************************************************ 310 * DefaultHandler_QueryInterface (IUnknown) 311 * 312 * See Windows documentation for more details on IUnknown methods. 313 */ 314 static HRESULT WINAPI DefaultHandler_QueryInterface( 315 IOleObject* iface, 316 REFIID riid, 317 void** ppvObject) 318 { 319 DefaultHandler *This = impl_from_IOleObject(iface); 320 321 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject); 322 } 323 324 /************************************************************************ 325 * DefaultHandler_AddRef (IUnknown) 326 * 327 * See Windows documentation for more details on IUnknown methods. 328 */ 329 static ULONG WINAPI DefaultHandler_AddRef( 330 IOleObject* iface) 331 { 332 DefaultHandler *This = impl_from_IOleObject(iface); 333 334 return IUnknown_AddRef(This->outerUnknown); 335 } 336 337 /************************************************************************ 338 * DefaultHandler_Release (IUnknown) 339 * 340 * See Windows documentation for more details on IUnknown methods. 341 */ 342 static ULONG WINAPI DefaultHandler_Release( 343 IOleObject* iface) 344 { 345 DefaultHandler *This = impl_from_IOleObject(iface); 346 347 return IUnknown_Release(This->outerUnknown); 348 } 349 350 /************************************************************************ 351 * DefaultHandler_SetClientSite (IOleObject) 352 * 353 * The default handler's implementation of this method only keeps the 354 * client site pointer for future reference. 355 * 356 * See Windows documentation for more details on IOleObject methods. 357 */ 358 static HRESULT WINAPI DefaultHandler_SetClientSite( 359 IOleObject* iface, 360 IOleClientSite* pClientSite) 361 { 362 DefaultHandler *This = impl_from_IOleObject(iface); 363 HRESULT hr = S_OK; 364 365 TRACE("(%p, %p)\n", iface, pClientSite); 366 367 if (object_is_running(This)) 368 { 369 start_object_call( This ); 370 hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite); 371 end_object_call( This ); 372 } 373 374 /* 375 * Make sure we release the previous client site if there 376 * was one. 377 */ 378 if (This->clientSite) 379 IOleClientSite_Release(This->clientSite); 380 381 This->clientSite = pClientSite; 382 383 if (This->clientSite) 384 IOleClientSite_AddRef(This->clientSite); 385 386 return hr; 387 } 388 389 /************************************************************************ 390 * DefaultHandler_GetClientSite (IOleObject) 391 * 392 * The default handler's implementation of this method returns the 393 * last pointer set in IOleObject_SetClientSite. 394 * 395 * See Windows documentation for more details on IOleObject methods. 396 */ 397 static HRESULT WINAPI DefaultHandler_GetClientSite( 398 IOleObject* iface, 399 IOleClientSite** ppClientSite) 400 { 401 DefaultHandler *This = impl_from_IOleObject(iface); 402 403 if (!ppClientSite) 404 return E_POINTER; 405 406 *ppClientSite = This->clientSite; 407 408 if (This->clientSite) 409 IOleClientSite_AddRef(This->clientSite); 410 411 return S_OK; 412 } 413 414 /************************************************************************ 415 * DefaultHandler_SetHostNames (IOleObject) 416 * 417 * The default handler's implementation of this method just stores 418 * the strings and returns S_OK. 419 * 420 * See Windows documentation for more details on IOleObject methods. 421 */ 422 static HRESULT WINAPI DefaultHandler_SetHostNames( 423 IOleObject* iface, 424 LPCOLESTR szContainerApp, 425 LPCOLESTR szContainerObj) 426 { 427 DefaultHandler *This = impl_from_IOleObject(iface); 428 429 TRACE("(%p, %s, %s)\n", 430 iface, 431 debugstr_w(szContainerApp), 432 debugstr_w(szContainerObj)); 433 434 if (object_is_running(This)) 435 { 436 start_object_call( This ); 437 IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj); 438 end_object_call( This ); 439 } 440 441 /* Be sure to cleanup before re-assigning the strings. */ 442 HeapFree( GetProcessHeap(), 0, This->containerApp ); 443 This->containerApp = NULL; 444 HeapFree( GetProcessHeap(), 0, This->containerObj ); 445 This->containerObj = NULL; 446 447 if (szContainerApp) 448 { 449 if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0, 450 (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) ))) 451 lstrcpyW( This->containerApp, szContainerApp ); 452 } 453 454 if (szContainerObj) 455 { 456 if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0, 457 (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) ))) 458 lstrcpyW( This->containerObj, szContainerObj ); 459 } 460 return S_OK; 461 } 462 463 static void release_delegates(DefaultHandler *This) 464 { 465 if (This->pDataDelegate) 466 { 467 IDataObject_Release(This->pDataDelegate); 468 This->pDataDelegate = NULL; 469 } 470 if (This->pPSDelegate) 471 { 472 IPersistStorage_Release(This->pPSDelegate); 473 This->pPSDelegate = NULL; 474 } 475 if (This->pOleDelegate) 476 { 477 IOleObject_Release(This->pOleDelegate); 478 This->pOleDelegate = NULL; 479 } 480 } 481 482 /* undoes the work done by DefaultHandler_Run */ 483 static void DefaultHandler_Stop(DefaultHandler *This) 484 { 485 IOleCacheControl *cache_ctrl; 486 HRESULT hr; 487 488 if (This->object_state == object_state_not_running) 489 return; 490 491 hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl ); 492 if (SUCCEEDED(hr)) 493 { 494 hr = IOleCacheControl_OnStop( cache_ctrl ); 495 IOleCacheControl_Release( cache_ctrl ); 496 } 497 498 IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn); 499 500 if (This->dataAdviseHolder) 501 DataAdviseHolder_OnDisconnect(This->dataAdviseHolder); 502 503 This->object_state = object_state_not_running; 504 release_delegates( This ); 505 } 506 507 /************************************************************************ 508 * DefaultHandler_Close (IOleObject) 509 * 510 * The default handler's implementation of this method is meaningless 511 * without a running server so it does nothing. 512 * 513 * See Windows documentation for more details on IOleObject methods. 514 */ 515 static HRESULT WINAPI DefaultHandler_Close( 516 IOleObject* iface, 517 DWORD dwSaveOption) 518 { 519 DefaultHandler *This = impl_from_IOleObject(iface); 520 HRESULT hr; 521 522 TRACE("(%d)\n", dwSaveOption); 523 524 if (!object_is_running(This)) 525 return S_OK; 526 527 start_object_call( This ); 528 hr = IOleObject_Close(This->pOleDelegate, dwSaveOption); 529 end_object_call( This ); 530 531 DefaultHandler_Stop(This); 532 533 return hr; 534 } 535 536 /************************************************************************ 537 * DefaultHandler_SetMoniker (IOleObject) 538 * 539 * The default handler's implementation of this method does nothing. 540 * 541 * See Windows documentation for more details on IOleObject methods. 542 */ 543 static HRESULT WINAPI DefaultHandler_SetMoniker( 544 IOleObject* iface, 545 DWORD dwWhichMoniker, 546 IMoniker* pmk) 547 { 548 DefaultHandler *This = impl_from_IOleObject(iface); 549 HRESULT hr = S_OK; 550 551 TRACE("(%p, %d, %p)\n", iface, dwWhichMoniker, pmk); 552 553 if (object_is_running(This)) 554 { 555 start_object_call( This ); 556 hr = IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk); 557 end_object_call( This ); 558 } 559 560 return hr; 561 } 562 563 /************************************************************************ 564 * DefaultHandler_GetMoniker (IOleObject) 565 * 566 * Delegate this request to the client site if we have one. 567 * 568 * See Windows documentation for more details on IOleObject methods. 569 */ 570 static HRESULT WINAPI DefaultHandler_GetMoniker( 571 IOleObject* iface, 572 DWORD dwAssign, 573 DWORD dwWhichMoniker, 574 IMoniker** ppmk) 575 { 576 DefaultHandler *This = impl_from_IOleObject(iface); 577 HRESULT hr; 578 579 TRACE("(%p, %d, %d, %p)\n", 580 iface, dwAssign, dwWhichMoniker, ppmk); 581 582 if (object_is_running(This)) 583 { 584 start_object_call( This ); 585 hr = IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker, 586 ppmk); 587 end_object_call( This ); 588 return hr; 589 } 590 591 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */ 592 if (This->clientSite) 593 { 594 return IOleClientSite_GetMoniker(This->clientSite, 595 dwAssign, 596 dwWhichMoniker, 597 ppmk); 598 599 } 600 601 return E_FAIL; 602 } 603 604 /************************************************************************ 605 * DefaultHandler_InitFromData (IOleObject) 606 * 607 * This method is meaningless if the server is not running 608 * 609 * See Windows documentation for more details on IOleObject methods. 610 */ 611 static HRESULT WINAPI DefaultHandler_InitFromData( 612 IOleObject* iface, 613 IDataObject* pDataObject, 614 BOOL fCreation, 615 DWORD dwReserved) 616 { 617 DefaultHandler *This = impl_from_IOleObject(iface); 618 HRESULT hr = OLE_E_NOTRUNNING; 619 620 TRACE("(%p, %p, %d, %d)\n", 621 iface, pDataObject, fCreation, dwReserved); 622 623 if (object_is_running(This)) 624 { 625 start_object_call( This ); 626 hr = IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation, 627 dwReserved); 628 end_object_call( This ); 629 } 630 631 return hr; 632 } 633 634 /************************************************************************ 635 * DefaultHandler_GetClipboardData (IOleObject) 636 * 637 * This method is meaningless if the server is not running 638 * 639 * See Windows documentation for more details on IOleObject methods. 640 */ 641 static HRESULT WINAPI DefaultHandler_GetClipboardData( 642 IOleObject* iface, 643 DWORD dwReserved, 644 IDataObject** ppDataObject) 645 { 646 DefaultHandler *This = impl_from_IOleObject(iface); 647 HRESULT hr = OLE_E_NOTRUNNING; 648 649 TRACE("(%p, %d, %p)\n", 650 iface, dwReserved, ppDataObject); 651 652 if (object_is_running(This)) 653 { 654 start_object_call( This ); 655 hr = IOleObject_GetClipboardData(This->pOleDelegate, dwReserved, 656 ppDataObject); 657 end_object_call( This ); 658 } 659 660 return hr; 661 } 662 663 static HRESULT WINAPI DefaultHandler_DoVerb( 664 IOleObject* iface, 665 LONG iVerb, 666 struct tagMSG* lpmsg, 667 IOleClientSite* pActiveSite, 668 LONG lindex, 669 HWND hwndParent, 670 LPCRECT lprcPosRect) 671 { 672 DefaultHandler *This = impl_from_IOleObject(iface); 673 IRunnableObject *pRunnableObj = &This->IRunnableObject_iface; 674 HRESULT hr; 675 676 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect)); 677 678 hr = IRunnableObject_Run(pRunnableObj, NULL); 679 if (FAILED(hr)) return hr; 680 681 start_object_call( This ); 682 hr = IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite, 683 lindex, hwndParent, lprcPosRect); 684 end_object_call( This ); 685 686 return hr; 687 } 688 689 /************************************************************************ 690 * DefaultHandler_EnumVerbs (IOleObject) 691 * 692 * The default handler implementation of this method simply delegates 693 * to OleRegEnumVerbs 694 * 695 * See Windows documentation for more details on IOleObject methods. 696 */ 697 static HRESULT WINAPI DefaultHandler_EnumVerbs( 698 IOleObject* iface, 699 IEnumOLEVERB** ppEnumOleVerb) 700 { 701 DefaultHandler *This = impl_from_IOleObject(iface); 702 HRESULT hr = OLE_S_USEREG; 703 704 TRACE("(%p, %p)\n", iface, ppEnumOleVerb); 705 706 if (object_is_running(This)) 707 { 708 start_object_call( This ); 709 hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb); 710 end_object_call( This ); 711 } 712 713 if (hr == OLE_S_USEREG) 714 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb); 715 else 716 return hr; 717 } 718 719 static HRESULT WINAPI DefaultHandler_Update( 720 IOleObject* iface) 721 { 722 DefaultHandler *This = impl_from_IOleObject(iface); 723 HRESULT hr; 724 725 TRACE("(%p)\n", iface); 726 727 if (!object_is_running(This)) 728 { 729 FIXME("Should run object\n"); 730 return E_NOTIMPL; 731 } 732 733 start_object_call( This ); 734 hr = IOleObject_Update(This->pOleDelegate); 735 end_object_call( This ); 736 737 return hr; 738 } 739 740 /************************************************************************ 741 * DefaultHandler_IsUpToDate (IOleObject) 742 * 743 * This method is meaningless if the server is not running 744 * 745 * See Windows documentation for more details on IOleObject methods. 746 */ 747 static HRESULT WINAPI DefaultHandler_IsUpToDate( 748 IOleObject* iface) 749 { 750 DefaultHandler *This = impl_from_IOleObject(iface); 751 HRESULT hr = OLE_E_NOTRUNNING; 752 TRACE("(%p)\n", iface); 753 754 if (object_is_running(This)) 755 { 756 start_object_call( This ); 757 hr = IOleObject_IsUpToDate(This->pOleDelegate); 758 end_object_call( This ); 759 } 760 761 return hr; 762 } 763 764 /************************************************************************ 765 * DefaultHandler_GetUserClassID (IOleObject) 766 * 767 * TODO: Map to a new class ID if emulation is active. 768 * 769 * See Windows documentation for more details on IOleObject methods. 770 */ 771 static HRESULT WINAPI DefaultHandler_GetUserClassID( 772 IOleObject* iface, 773 CLSID* pClsid) 774 { 775 DefaultHandler *This = impl_from_IOleObject(iface); 776 HRESULT hr; 777 778 TRACE("(%p, %p)\n", iface, pClsid); 779 780 if (object_is_running(This)) 781 { 782 start_object_call( This ); 783 hr = IOleObject_GetUserClassID(This->pOleDelegate, pClsid); 784 end_object_call( This ); 785 return hr; 786 } 787 788 if (!pClsid) 789 return E_POINTER; 790 791 *pClsid = This->clsid; 792 793 return S_OK; 794 } 795 796 /************************************************************************ 797 * DefaultHandler_GetUserType (IOleObject) 798 * 799 * The default handler implementation of this method simply delegates 800 * to OleRegGetUserType 801 * 802 * See Windows documentation for more details on IOleObject methods. 803 */ 804 static HRESULT WINAPI DefaultHandler_GetUserType( 805 IOleObject* iface, 806 DWORD dwFormOfType, 807 LPOLESTR* pszUserType) 808 { 809 DefaultHandler *This = impl_from_IOleObject(iface); 810 HRESULT hr; 811 812 TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType); 813 if (object_is_running(This)) 814 { 815 start_object_call( This ); 816 hr = IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType); 817 end_object_call( This ); 818 return hr; 819 } 820 821 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType); 822 } 823 824 /************************************************************************ 825 * DefaultHandler_SetExtent (IOleObject) 826 * 827 * This method is meaningless if the server is not running 828 * 829 * See Windows documentation for more details on IOleObject methods. 830 */ 831 static HRESULT WINAPI DefaultHandler_SetExtent( 832 IOleObject* iface, 833 DWORD dwDrawAspect, 834 SIZEL* psizel) 835 { 836 DefaultHandler *This = impl_from_IOleObject(iface); 837 HRESULT hr = OLE_E_NOTRUNNING; 838 839 TRACE("(%p, %x, (%d x %d))\n", iface, 840 dwDrawAspect, psizel->cx, psizel->cy); 841 842 if (object_is_running(This)) 843 { 844 start_object_call( This ); 845 hr = IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel); 846 end_object_call( This ); 847 } 848 849 return hr; 850 } 851 852 /************************************************************************ 853 * DefaultHandler_GetExtent (IOleObject) 854 * 855 * The default handler's implementation of this method returns uses 856 * the cache to locate the aspect and extract the extent from it. 857 * 858 * See Windows documentation for more details on IOleObject methods. 859 */ 860 static HRESULT WINAPI DefaultHandler_GetExtent( 861 IOleObject* iface, 862 DWORD dwDrawAspect, 863 SIZEL* psizel) 864 { 865 DVTARGETDEVICE* targetDevice; 866 IViewObject2* cacheView = NULL; 867 HRESULT hres; 868 869 DefaultHandler *This = impl_from_IOleObject(iface); 870 871 TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel); 872 873 if (object_is_running(This)) 874 { 875 start_object_call( This ); 876 hres = IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel); 877 end_object_call( This ); 878 return hres; 879 } 880 881 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView); 882 if (FAILED(hres)) 883 return E_UNEXPECTED; 884 885 /* 886 * Prepare the call to the cache's GetExtent method. 887 * 888 * Here we would build a valid DVTARGETDEVICE structure 889 * but, since we are calling into the data cache, we 890 * know its implementation and we'll skip this 891 * extra work until later. 892 */ 893 targetDevice = NULL; 894 895 hres = IViewObject2_GetExtent(cacheView, 896 dwDrawAspect, 897 -1, 898 targetDevice, 899 psizel); 900 901 IViewObject2_Release(cacheView); 902 903 return hres; 904 } 905 906 /************************************************************************ 907 * DefaultHandler_Advise (IOleObject) 908 * 909 * The default handler's implementation of this method simply 910 * delegates to the OleAdviseHolder. 911 * 912 * See Windows documentation for more details on IOleObject methods. 913 */ 914 static HRESULT WINAPI DefaultHandler_Advise( 915 IOleObject* iface, 916 IAdviseSink* pAdvSink, 917 DWORD* pdwConnection) 918 { 919 HRESULT hres = S_OK; 920 DefaultHandler *This = impl_from_IOleObject(iface); 921 922 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection); 923 924 /* Make sure we have an advise holder before we start. */ 925 if (!This->oleAdviseHolder) 926 hres = CreateOleAdviseHolder(&This->oleAdviseHolder); 927 928 if (SUCCEEDED(hres)) 929 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder, 930 pAdvSink, 931 pdwConnection); 932 933 return hres; 934 } 935 936 /************************************************************************ 937 * DefaultHandler_Unadvise (IOleObject) 938 * 939 * The default handler's implementation of this method simply 940 * delegates to the OleAdviseHolder. 941 * 942 * See Windows documentation for more details on IOleObject methods. 943 */ 944 static HRESULT WINAPI DefaultHandler_Unadvise( 945 IOleObject* iface, 946 DWORD dwConnection) 947 { 948 DefaultHandler *This = impl_from_IOleObject(iface); 949 950 TRACE("(%p, %d)\n", iface, dwConnection); 951 952 /* 953 * If we don't have an advise holder yet, it means we don't have 954 * a connection. 955 */ 956 if (!This->oleAdviseHolder) 957 return OLE_E_NOCONNECTION; 958 959 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder, 960 dwConnection); 961 } 962 963 /************************************************************************ 964 * DefaultHandler_EnumAdvise (IOleObject) 965 * 966 * The default handler's implementation of this method simply 967 * delegates to the OleAdviseHolder. 968 * 969 * See Windows documentation for more details on IOleObject methods. 970 */ 971 static HRESULT WINAPI DefaultHandler_EnumAdvise( 972 IOleObject* iface, 973 IEnumSTATDATA** ppenumAdvise) 974 { 975 DefaultHandler *This = impl_from_IOleObject(iface); 976 977 TRACE("(%p, %p)\n", iface, ppenumAdvise); 978 979 if (!ppenumAdvise) 980 return E_POINTER; 981 982 *ppenumAdvise = NULL; 983 984 if (!This->oleAdviseHolder) 985 return S_OK; 986 987 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise); 988 } 989 990 /************************************************************************ 991 * DefaultHandler_GetMiscStatus (IOleObject) 992 * 993 * The default handler's implementation of this method simply delegates 994 * to OleRegGetMiscStatus. 995 * 996 * See Windows documentation for more details on IOleObject methods. 997 */ 998 static HRESULT WINAPI DefaultHandler_GetMiscStatus( 999 IOleObject* iface, 1000 DWORD dwAspect, 1001 DWORD* pdwStatus) 1002 { 1003 HRESULT hres; 1004 DefaultHandler *This = impl_from_IOleObject(iface); 1005 1006 TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus); 1007 1008 if (object_is_running(This)) 1009 { 1010 start_object_call( This ); 1011 hres = IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus); 1012 end_object_call( This ); 1013 return hres; 1014 } 1015 1016 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus); 1017 1018 if (FAILED(hres)) 1019 *pdwStatus = 0; 1020 1021 return hres; 1022 } 1023 1024 /************************************************************************ 1025 * DefaultHandler_SetColorScheme (IOleObject) 1026 * 1027 * This method is meaningless if the server is not running 1028 * 1029 * See Windows documentation for more details on IOleObject methods. 1030 */ 1031 static HRESULT WINAPI DefaultHandler_SetColorScheme( 1032 IOleObject* iface, 1033 struct tagLOGPALETTE* pLogpal) 1034 { 1035 DefaultHandler *This = impl_from_IOleObject(iface); 1036 HRESULT hr = OLE_E_NOTRUNNING; 1037 1038 TRACE("(%p, %p))\n", iface, pLogpal); 1039 1040 if (object_is_running(This)) 1041 { 1042 start_object_call( This ); 1043 hr = IOleObject_SetColorScheme(This->pOleDelegate, pLogpal); 1044 end_object_call( This ); 1045 } 1046 1047 return hr; 1048 } 1049 1050 /********************************************************* 1051 * Methods implementation for the IDataObject part of 1052 * the DefaultHandler class. 1053 */ 1054 1055 /************************************************************************ 1056 * DefaultHandler_IDataObject_QueryInterface (IUnknown) 1057 * 1058 * See Windows documentation for more details on IUnknown methods. 1059 */ 1060 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface( 1061 IDataObject* iface, 1062 REFIID riid, 1063 void** ppvObject) 1064 { 1065 DefaultHandler *This = impl_from_IDataObject(iface); 1066 1067 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject); 1068 } 1069 1070 /************************************************************************ 1071 * DefaultHandler_IDataObject_AddRef (IUnknown) 1072 * 1073 * See Windows documentation for more details on IUnknown methods. 1074 */ 1075 static ULONG WINAPI DefaultHandler_IDataObject_AddRef( 1076 IDataObject* iface) 1077 { 1078 DefaultHandler *This = impl_from_IDataObject(iface); 1079 1080 return IUnknown_AddRef(This->outerUnknown); 1081 } 1082 1083 /************************************************************************ 1084 * DefaultHandler_IDataObject_Release (IUnknown) 1085 * 1086 * See Windows documentation for more details on IUnknown methods. 1087 */ 1088 static ULONG WINAPI DefaultHandler_IDataObject_Release( 1089 IDataObject* iface) 1090 { 1091 DefaultHandler *This = impl_from_IDataObject(iface); 1092 1093 return IUnknown_Release(This->outerUnknown); 1094 } 1095 1096 /************************************************************************ 1097 * DefaultHandler_GetData 1098 * 1099 * Get Data from a source dataobject using format pformatetcIn->cfFormat 1100 * See Windows documentation for more details on GetData. 1101 * Default handler's implementation of this method delegates to the cache. 1102 */ 1103 static HRESULT WINAPI DefaultHandler_GetData( 1104 IDataObject* iface, 1105 LPFORMATETC pformatetcIn, 1106 STGMEDIUM* pmedium) 1107 { 1108 IDataObject* cacheDataObject = NULL; 1109 HRESULT hres; 1110 1111 DefaultHandler *This = impl_from_IDataObject(iface); 1112 1113 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium); 1114 1115 hres = IUnknown_QueryInterface(This->dataCache, 1116 &IID_IDataObject, 1117 (void**)&cacheDataObject); 1118 1119 if (FAILED(hres)) 1120 return E_UNEXPECTED; 1121 1122 hres = IDataObject_GetData(cacheDataObject, 1123 pformatetcIn, 1124 pmedium); 1125 1126 IDataObject_Release(cacheDataObject); 1127 1128 if (hres == S_OK) return hres; 1129 1130 if (object_is_running( This )) 1131 { 1132 start_object_call(This); 1133 hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium); 1134 end_object_call(This); 1135 if (hres == S_OK) return hres; 1136 } 1137 1138 /* Query running state again, as the object may have closed during _GetData call */ 1139 if (!object_is_running( This )) 1140 hres = OLE_E_NOTRUNNING; 1141 1142 return hres; 1143 } 1144 1145 static HRESULT WINAPI DefaultHandler_GetDataHere( 1146 IDataObject* iface, 1147 LPFORMATETC pformatetc, 1148 STGMEDIUM* pmedium) 1149 { 1150 FIXME(": Stub\n"); 1151 return E_NOTIMPL; 1152 } 1153 1154 /************************************************************************ 1155 * DefaultHandler_QueryGetData (IDataObject) 1156 * 1157 * The default handler's implementation of this method delegates to 1158 * the cache. 1159 * 1160 * See Windows documentation for more details on IDataObject methods. 1161 */ 1162 static HRESULT WINAPI DefaultHandler_QueryGetData( 1163 IDataObject* iface, 1164 LPFORMATETC pformatetc) 1165 { 1166 IDataObject* cacheDataObject = NULL; 1167 HRESULT hres; 1168 1169 DefaultHandler *This = impl_from_IDataObject(iface); 1170 1171 TRACE("(%p, %p)\n", iface, pformatetc); 1172 1173 hres = IUnknown_QueryInterface(This->dataCache, 1174 &IID_IDataObject, 1175 (void**)&cacheDataObject); 1176 1177 if (FAILED(hres)) 1178 return E_UNEXPECTED; 1179 1180 hres = IDataObject_QueryGetData(cacheDataObject, 1181 pformatetc); 1182 1183 IDataObject_Release(cacheDataObject); 1184 1185 if (hres == S_OK) return hres; 1186 1187 if (object_is_running( This )) 1188 { 1189 start_object_call( This ); 1190 hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc); 1191 end_object_call( This ); 1192 if (hres == S_OK) return hres; 1193 } 1194 1195 /* Query running state again, as the object may have closed during _QueryGetData call */ 1196 if (!object_is_running( This )) 1197 hres = OLE_E_NOTRUNNING; 1198 1199 return hres; 1200 } 1201 1202 /************************************************************************ 1203 * DefaultHandler_GetCanonicalFormatEtc (IDataObject) 1204 * 1205 * This method is meaningless if the server is not running 1206 * 1207 * See Windows documentation for more details on IDataObject methods. 1208 */ 1209 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc( 1210 IDataObject* iface, 1211 LPFORMATETC pformatetcIn, 1212 LPFORMATETC pformatetcOut) 1213 { 1214 DefaultHandler *This = impl_from_IDataObject(iface); 1215 HRESULT hr; 1216 1217 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut); 1218 1219 if (!object_is_running( This )) 1220 return OLE_E_NOTRUNNING; 1221 1222 start_object_call( This ); 1223 hr = IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut); 1224 end_object_call( This ); 1225 1226 return hr; 1227 } 1228 1229 /************************************************************************ 1230 * DefaultHandler_SetData (IDataObject) 1231 * 1232 * The default handler's implementation of this method delegates to 1233 * the cache. 1234 * 1235 * See Windows documentation for more details on IDataObject methods. 1236 */ 1237 static HRESULT WINAPI DefaultHandler_SetData( 1238 IDataObject* iface, 1239 LPFORMATETC pformatetc, 1240 STGMEDIUM* pmedium, 1241 BOOL fRelease) 1242 { 1243 DefaultHandler *This = impl_from_IDataObject(iface); 1244 IDataObject* cacheDataObject = NULL; 1245 HRESULT hres; 1246 1247 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease); 1248 1249 hres = IUnknown_QueryInterface(This->dataCache, 1250 &IID_IDataObject, 1251 (void**)&cacheDataObject); 1252 1253 if (FAILED(hres)) 1254 return E_UNEXPECTED; 1255 1256 hres = IDataObject_SetData(cacheDataObject, 1257 pformatetc, 1258 pmedium, 1259 fRelease); 1260 1261 IDataObject_Release(cacheDataObject); 1262 1263 return hres; 1264 } 1265 1266 /************************************************************************ 1267 * DefaultHandler_EnumFormatEtc (IDataObject) 1268 * 1269 * The default handler's implementation of This method simply delegates 1270 * to OleRegEnumFormatEtc. 1271 * 1272 * See Windows documentation for more details on IDataObject methods. 1273 */ 1274 static HRESULT WINAPI DefaultHandler_EnumFormatEtc( 1275 IDataObject* iface, 1276 DWORD dwDirection, 1277 IEnumFORMATETC** ppenumFormatEtc) 1278 { 1279 DefaultHandler *This = impl_from_IDataObject(iface); 1280 1281 TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc); 1282 1283 return OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc); 1284 } 1285 1286 /************************************************************************ 1287 * DefaultHandler_DAdvise (IDataObject) 1288 * 1289 * The default handler's implementation of this method simply 1290 * delegates to the DataAdviseHolder. 1291 * 1292 * See Windows documentation for more details on IDataObject methods. 1293 */ 1294 static HRESULT WINAPI DefaultHandler_DAdvise( 1295 IDataObject* iface, 1296 FORMATETC* pformatetc, 1297 DWORD advf, 1298 IAdviseSink* pAdvSink, 1299 DWORD* pdwConnection) 1300 { 1301 HRESULT hres = S_OK; 1302 DefaultHandler *This = impl_from_IDataObject(iface); 1303 1304 TRACE("(%p, %p, %d, %p, %p)\n", 1305 iface, pformatetc, advf, pAdvSink, pdwConnection); 1306 1307 /* Make sure we have a data advise holder before we start. */ 1308 if (!This->dataAdviseHolder) 1309 { 1310 hres = CreateDataAdviseHolder(&This->dataAdviseHolder); 1311 if (SUCCEEDED(hres) && object_is_running( This )) 1312 { 1313 start_object_call( This ); 1314 DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate); 1315 end_object_call( This ); 1316 } 1317 } 1318 1319 if (SUCCEEDED(hres)) 1320 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder, 1321 iface, 1322 pformatetc, 1323 advf, 1324 pAdvSink, 1325 pdwConnection); 1326 1327 return hres; 1328 } 1329 1330 /************************************************************************ 1331 * DefaultHandler_DUnadvise (IDataObject) 1332 * 1333 * The default handler's implementation of this method simply 1334 * delegates to the DataAdviseHolder. 1335 * 1336 * See Windows documentation for more details on IDataObject methods. 1337 */ 1338 static HRESULT WINAPI DefaultHandler_DUnadvise( 1339 IDataObject* iface, 1340 DWORD dwConnection) 1341 { 1342 DefaultHandler *This = impl_from_IDataObject(iface); 1343 1344 TRACE("(%p, %d)\n", iface, dwConnection); 1345 1346 /* 1347 * If we don't have a data advise holder yet, it means that 1348 * we don't have any connections.. 1349 */ 1350 if (!This->dataAdviseHolder) 1351 return OLE_E_NOCONNECTION; 1352 1353 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder, 1354 dwConnection); 1355 } 1356 1357 /************************************************************************ 1358 * DefaultHandler_EnumDAdvise (IDataObject) 1359 * 1360 * The default handler's implementation of this method simply 1361 * delegates to the DataAdviseHolder. 1362 * 1363 * See Windows documentation for more details on IDataObject methods. 1364 */ 1365 static HRESULT WINAPI DefaultHandler_EnumDAdvise( 1366 IDataObject* iface, 1367 IEnumSTATDATA** ppenumAdvise) 1368 { 1369 DefaultHandler *This = impl_from_IDataObject(iface); 1370 1371 TRACE("(%p, %p)\n", iface, ppenumAdvise); 1372 1373 if (!ppenumAdvise) 1374 return E_POINTER; 1375 1376 *ppenumAdvise = NULL; 1377 1378 /* If we have a data advise holder object, delegate. */ 1379 if (This->dataAdviseHolder) 1380 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder, 1381 ppenumAdvise); 1382 1383 return S_OK; 1384 } 1385 1386 /********************************************************* 1387 * Methods implementation for the IRunnableObject part 1388 * of the DefaultHandler class. 1389 */ 1390 1391 /************************************************************************ 1392 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown) 1393 * 1394 * See Windows documentation for more details on IUnknown methods. 1395 */ 1396 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface( 1397 IRunnableObject* iface, 1398 REFIID riid, 1399 void** ppvObject) 1400 { 1401 DefaultHandler *This = impl_from_IRunnableObject(iface); 1402 1403 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject); 1404 } 1405 1406 /************************************************************************ 1407 * DefaultHandler_IRunnableObject_AddRef (IUnknown) 1408 * 1409 * See Windows documentation for more details on IUnknown methods. 1410 */ 1411 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef( 1412 IRunnableObject* iface) 1413 { 1414 DefaultHandler *This = impl_from_IRunnableObject(iface); 1415 1416 return IUnknown_AddRef(This->outerUnknown); 1417 } 1418 1419 /************************************************************************ 1420 * DefaultHandler_IRunnableObject_Release (IUnknown) 1421 * 1422 * See Windows documentation for more details on IUnknown methods. 1423 */ 1424 static ULONG WINAPI DefaultHandler_IRunnableObject_Release( 1425 IRunnableObject* iface) 1426 { 1427 DefaultHandler *This = impl_from_IRunnableObject(iface); 1428 1429 return IUnknown_Release(This->outerUnknown); 1430 } 1431 1432 /************************************************************************ 1433 * DefaultHandler_GetRunningClass (IRunnableObject) 1434 * 1435 * See Windows documentation for more details on IRunnableObject methods. 1436 */ 1437 static HRESULT WINAPI DefaultHandler_GetRunningClass( 1438 IRunnableObject* iface, 1439 LPCLSID lpClsid) 1440 { 1441 FIXME("()\n"); 1442 return S_OK; 1443 } 1444 1445 static HRESULT WINAPI DefaultHandler_Run( 1446 IRunnableObject* iface, 1447 IBindCtx* pbc) 1448 { 1449 DefaultHandler *This = impl_from_IRunnableObject(iface); 1450 HRESULT hr; 1451 IOleCacheControl *cache_ctrl; 1452 1453 FIXME("(%p): semi-stub\n", pbc); 1454 1455 /* already running? if so nothing to do */ 1456 if (object_is_running(This)) 1457 return S_OK; 1458 1459 release_delegates(This); 1460 1461 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, 1462 &IID_IOleObject, (void **)&This->pOleDelegate); 1463 if (FAILED(hr)) 1464 return hr; 1465 1466 hr = IOleObject_Advise(This->pOleDelegate, &This->IAdviseSink_iface, &This->dwAdvConn); 1467 if (FAILED(hr)) goto fail; 1468 1469 if (This->clientSite) 1470 { 1471 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite); 1472 if (FAILED(hr)) goto fail; 1473 } 1474 1475 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, 1476 (void **)&This->pPSDelegate); 1477 if (FAILED(hr)) goto fail; 1478 1479 if (This->storage_state == storage_state_initialised) 1480 hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage); 1481 else if (This->storage_state == storage_state_loaded) 1482 hr = IPersistStorage_Load(This->pPSDelegate, This->storage); 1483 if (FAILED(hr)) goto fail; 1484 1485 if (This->containerApp) 1486 { 1487 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp, 1488 This->containerObj); 1489 if (FAILED(hr)) goto fail; 1490 } 1491 1492 /* FIXME: do more stuff here: 1493 * - IOleObject_GetMiscStatus 1494 * - IOleObject_GetMoniker 1495 */ 1496 1497 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, 1498 (void **)&This->pDataDelegate); 1499 if (FAILED(hr)) goto fail; 1500 1501 This->object_state = object_state_running; 1502 1503 if (This->dataAdviseHolder) 1504 { 1505 hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate); 1506 if (FAILED(hr)) goto fail; 1507 } 1508 1509 hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl ); 1510 if (FAILED(hr)) goto fail; 1511 hr = IOleCacheControl_OnRun( cache_ctrl, This->pDataDelegate ); 1512 IOleCacheControl_Release( cache_ctrl ); 1513 if (FAILED(hr)) goto fail; 1514 1515 return hr; 1516 1517 fail: 1518 DefaultHandler_Stop(This); 1519 return hr; 1520 } 1521 1522 /************************************************************************ 1523 * DefaultHandler_IsRunning (IRunnableObject) 1524 * 1525 * See Windows documentation for more details on IRunnableObject methods. 1526 */ 1527 static BOOL WINAPI DefaultHandler_IsRunning( 1528 IRunnableObject* iface) 1529 { 1530 DefaultHandler *This = impl_from_IRunnableObject(iface); 1531 1532 TRACE("()\n"); 1533 1534 if (This->object_state == object_state_running) 1535 return TRUE; 1536 else 1537 return FALSE; 1538 } 1539 1540 /************************************************************************ 1541 * DefaultHandler_LockRunning (IRunnableObject) 1542 * 1543 * See Windows documentation for more details on IRunnableObject methods. 1544 */ 1545 static HRESULT WINAPI DefaultHandler_LockRunning( 1546 IRunnableObject* iface, 1547 BOOL fLock, 1548 BOOL fLastUnlockCloses) 1549 { 1550 FIXME("()\n"); 1551 return S_OK; 1552 } 1553 1554 /************************************************************************ 1555 * DefaultHandler_SetContainedObject (IRunnableObject) 1556 * 1557 * See Windows documentation for more details on IRunnableObject methods. 1558 */ 1559 static HRESULT WINAPI DefaultHandler_SetContainedObject( 1560 IRunnableObject* iface, 1561 BOOL fContained) 1562 { 1563 FIXME("()\n"); 1564 return S_OK; 1565 } 1566 1567 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface( 1568 IAdviseSink *iface, 1569 REFIID riid, 1570 void **ppvObject) 1571 { 1572 if (IsEqualIID(riid, &IID_IUnknown) || 1573 IsEqualIID(riid, &IID_IAdviseSink)) 1574 { 1575 *ppvObject = iface; 1576 IAdviseSink_AddRef(iface); 1577 return S_OK; 1578 } 1579 1580 return E_NOINTERFACE; 1581 } 1582 1583 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef( 1584 IAdviseSink *iface) 1585 { 1586 DefaultHandler *This = impl_from_IAdviseSink(iface); 1587 1588 return IUnknown_AddRef(&This->IUnknown_iface); 1589 } 1590 1591 static ULONG WINAPI DefaultHandler_IAdviseSink_Release( 1592 IAdviseSink *iface) 1593 { 1594 DefaultHandler *This = impl_from_IAdviseSink(iface); 1595 1596 return IUnknown_Release(&This->IUnknown_iface); 1597 } 1598 1599 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange( 1600 IAdviseSink *iface, 1601 FORMATETC *pFormatetc, 1602 STGMEDIUM *pStgmed) 1603 { 1604 FIXME(": stub\n"); 1605 } 1606 1607 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange( 1608 IAdviseSink *iface, 1609 DWORD dwAspect, 1610 LONG lindex) 1611 { 1612 FIXME(": stub\n"); 1613 } 1614 1615 static void WINAPI DefaultHandler_IAdviseSink_OnRename( 1616 IAdviseSink *iface, 1617 IMoniker *pmk) 1618 { 1619 DefaultHandler *This = impl_from_IAdviseSink(iface); 1620 1621 TRACE("(%p)\n", pmk); 1622 1623 if (This->oleAdviseHolder) 1624 IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk); 1625 } 1626 1627 static void WINAPI DefaultHandler_IAdviseSink_OnSave( 1628 IAdviseSink *iface) 1629 { 1630 DefaultHandler *This = impl_from_IAdviseSink(iface); 1631 1632 TRACE("()\n"); 1633 1634 if (This->oleAdviseHolder) 1635 IOleAdviseHolder_SendOnSave(This->oleAdviseHolder); 1636 } 1637 1638 static void WINAPI DefaultHandler_IAdviseSink_OnClose( 1639 IAdviseSink *iface) 1640 { 1641 DefaultHandler *This = impl_from_IAdviseSink(iface); 1642 1643 TRACE("()\n"); 1644 1645 if (This->oleAdviseHolder) 1646 IOleAdviseHolder_SendOnClose(This->oleAdviseHolder); 1647 1648 if(!This->in_call) 1649 DefaultHandler_Stop(This); 1650 else 1651 { 1652 TRACE("OnClose during call. Deferring shutdown\n"); 1653 This->object_state = object_state_deferred_close; 1654 } 1655 } 1656 1657 /************************************************************************ 1658 * DefaultHandler_IPersistStorage_QueryInterface 1659 * 1660 */ 1661 static HRESULT WINAPI DefaultHandler_IPersistStorage_QueryInterface( 1662 IPersistStorage* iface, 1663 REFIID riid, 1664 void** ppvObject) 1665 { 1666 DefaultHandler *This = impl_from_IPersistStorage(iface); 1667 1668 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject); 1669 } 1670 1671 /************************************************************************ 1672 * DefaultHandler_IPersistStorage_AddRef 1673 * 1674 */ 1675 static ULONG WINAPI DefaultHandler_IPersistStorage_AddRef( 1676 IPersistStorage* iface) 1677 { 1678 DefaultHandler *This = impl_from_IPersistStorage(iface); 1679 1680 return IUnknown_AddRef(This->outerUnknown); 1681 } 1682 1683 /************************************************************************ 1684 * DefaultHandler_IPersistStorage_Release 1685 * 1686 */ 1687 static ULONG WINAPI DefaultHandler_IPersistStorage_Release( 1688 IPersistStorage* iface) 1689 { 1690 DefaultHandler *This = impl_from_IPersistStorage(iface); 1691 1692 return IUnknown_Release(This->outerUnknown); 1693 } 1694 1695 /************************************************************************ 1696 * DefaultHandler_IPersistStorage_GetClassID 1697 * 1698 */ 1699 static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID( 1700 IPersistStorage* iface, 1701 CLSID* clsid) 1702 { 1703 DefaultHandler *This = impl_from_IPersistStorage(iface); 1704 HRESULT hr; 1705 1706 TRACE("(%p)->(%p)\n", iface, clsid); 1707 1708 if(object_is_running(This)) 1709 { 1710 start_object_call( This ); 1711 hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid); 1712 end_object_call( This ); 1713 } 1714 else 1715 hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid); 1716 1717 return hr; 1718 } 1719 1720 /************************************************************************ 1721 * DefaultHandler_IPersistStorage_IsDirty 1722 * 1723 */ 1724 static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty( 1725 IPersistStorage* iface) 1726 { 1727 DefaultHandler *This = impl_from_IPersistStorage(iface); 1728 HRESULT hr; 1729 1730 TRACE("(%p)\n", iface); 1731 1732 hr = IPersistStorage_IsDirty(This->dataCache_PersistStg); 1733 if(hr != S_FALSE) return hr; 1734 1735 if(object_is_running(This)) 1736 { 1737 start_object_call( This ); 1738 hr = IPersistStorage_IsDirty(This->pPSDelegate); 1739 end_object_call( This ); 1740 } 1741 1742 return hr; 1743 } 1744 1745 /*********************************************************************** 1746 * 1747 * The format of '\1Ole' stream is as follows: 1748 * 1749 * DWORD Version == 0x02000001 1750 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded. 1751 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint 1752 * supplied by the app that creates the data structure. May be 1753 * ignored on processing]. 1754 * 1755 * DWORD Reserved == 0 1756 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data). 1757 * CLSID clsid - class id of object capable of processing the moniker 1758 * BYTE data[] - moniker data for a link 1759 */ 1760 1761 static const WCHAR OleStream[] = {1,'O','l','e',0}; 1762 typedef struct 1763 { 1764 DWORD version; 1765 DWORD flags; 1766 DWORD link_update_opt; 1767 DWORD res; 1768 DWORD moniker_size; 1769 } ole_stream_header_t; 1770 static const DWORD ole_stream_version = 0x02000001; 1771 1772 static HRESULT load_ole_stream(DefaultHandler *This, IStorage *storage) 1773 { 1774 IStream *stream; 1775 HRESULT hr; 1776 1777 hr = IStorage_OpenStream(storage, OleStream, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream); 1778 1779 if(SUCCEEDED(hr)) 1780 { 1781 DWORD read; 1782 ole_stream_header_t header; 1783 1784 hr = IStream_Read(stream, &header, sizeof(header), &read); 1785 if(hr == S_OK && read == sizeof(header) && header.version == ole_stream_version) 1786 { 1787 if(header.flags & 1) 1788 { 1789 /* FIXME: Read the moniker and deal with the link */ 1790 FIXME("Linked objects are not supported yet\n"); 1791 } 1792 } 1793 else 1794 { 1795 WARN("Incorrect OleStream header\n"); 1796 hr = DV_E_CLIPFORMAT; 1797 } 1798 IStream_Release(stream); 1799 } 1800 else 1801 hr = STORAGE_CreateOleStream(storage, 0); 1802 1803 return hr; 1804 } 1805 1806 /************************************************************************ 1807 * DefaultHandler_IPersistStorage_InitNew 1808 * 1809 */ 1810 static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew( 1811 IPersistStorage* iface, 1812 IStorage* pStg) 1813 { 1814 DefaultHandler *This = impl_from_IPersistStorage(iface); 1815 HRESULT hr; 1816 1817 TRACE("(%p)->(%p)\n", iface, pStg); 1818 hr = STORAGE_CreateOleStream(pStg, 0); 1819 if (hr != S_OK) return hr; 1820 1821 hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg); 1822 1823 if(SUCCEEDED(hr) && object_is_running(This)) 1824 { 1825 start_object_call( This ); 1826 hr = IPersistStorage_InitNew(This->pPSDelegate, pStg); 1827 end_object_call( This ); 1828 } 1829 1830 if(SUCCEEDED(hr)) 1831 { 1832 IStorage_AddRef(pStg); 1833 This->storage = pStg; 1834 This->storage_state = storage_state_initialised; 1835 } 1836 1837 return hr; 1838 } 1839 1840 1841 /************************************************************************ 1842 * DefaultHandler_IPersistStorage_Load 1843 * 1844 */ 1845 static HRESULT WINAPI DefaultHandler_IPersistStorage_Load( 1846 IPersistStorage* iface, 1847 IStorage* pStg) 1848 { 1849 DefaultHandler *This = impl_from_IPersistStorage(iface); 1850 HRESULT hr; 1851 1852 TRACE("(%p)->(%p)\n", iface, pStg); 1853 1854 hr = load_ole_stream(This, pStg); 1855 1856 if(SUCCEEDED(hr)) 1857 hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg); 1858 1859 if(SUCCEEDED(hr) && object_is_running(This)) 1860 { 1861 start_object_call( This ); 1862 hr = IPersistStorage_Load(This->pPSDelegate, pStg); 1863 end_object_call( This ); 1864 } 1865 1866 if(SUCCEEDED(hr)) 1867 { 1868 IStorage_AddRef(pStg); 1869 This->storage = pStg; 1870 This->storage_state = storage_state_loaded; 1871 } 1872 return hr; 1873 } 1874 1875 1876 /************************************************************************ 1877 * DefaultHandler_IPersistStorage_Save 1878 * 1879 */ 1880 static HRESULT WINAPI DefaultHandler_IPersistStorage_Save( 1881 IPersistStorage* iface, 1882 IStorage* pStgSave, 1883 BOOL fSameAsLoad) 1884 { 1885 DefaultHandler *This = impl_from_IPersistStorage(iface); 1886 HRESULT hr; 1887 1888 TRACE("(%p)->(%p, %d)\n", iface, pStgSave, fSameAsLoad); 1889 1890 hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad); 1891 if(SUCCEEDED(hr) && object_is_running(This)) 1892 { 1893 start_object_call( This ); 1894 hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad); 1895 end_object_call( This ); 1896 } 1897 1898 return hr; 1899 } 1900 1901 1902 /************************************************************************ 1903 * DefaultHandler_IPersistStorage_SaveCompleted 1904 * 1905 */ 1906 static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted( 1907 IPersistStorage* iface, 1908 IStorage* pStgNew) 1909 { 1910 DefaultHandler *This = impl_from_IPersistStorage(iface); 1911 HRESULT hr; 1912 1913 TRACE("(%p)->(%p)\n", iface, pStgNew); 1914 1915 hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew); 1916 1917 if(SUCCEEDED(hr) && object_is_running(This)) 1918 { 1919 start_object_call( This ); 1920 hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew); 1921 end_object_call( This ); 1922 } 1923 1924 if(pStgNew) 1925 { 1926 IStorage_AddRef(pStgNew); 1927 if(This->storage) IStorage_Release(This->storage); 1928 This->storage = pStgNew; 1929 This->storage_state = storage_state_loaded; 1930 } 1931 1932 return hr; 1933 } 1934 1935 1936 /************************************************************************ 1937 * DefaultHandler_IPersistStorage_HandsOffStorage 1938 * 1939 */ 1940 static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage( 1941 IPersistStorage* iface) 1942 { 1943 DefaultHandler *This = impl_from_IPersistStorage(iface); 1944 HRESULT hr; 1945 1946 TRACE("(%p)\n", iface); 1947 1948 hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg); 1949 1950 if(SUCCEEDED(hr) && object_is_running(This)) 1951 { 1952 start_object_call( This ); 1953 hr = IPersistStorage_HandsOffStorage(This->pPSDelegate); 1954 end_object_call( This ); 1955 } 1956 1957 if(This->storage) IStorage_Release(This->storage); 1958 This->storage = NULL; 1959 This->storage_state = storage_state_uninitialised; 1960 1961 return hr; 1962 } 1963 1964 1965 /* 1966 * Virtual function tables for the DefaultHandler class. 1967 */ 1968 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable = 1969 { 1970 DefaultHandler_QueryInterface, 1971 DefaultHandler_AddRef, 1972 DefaultHandler_Release, 1973 DefaultHandler_SetClientSite, 1974 DefaultHandler_GetClientSite, 1975 DefaultHandler_SetHostNames, 1976 DefaultHandler_Close, 1977 DefaultHandler_SetMoniker, 1978 DefaultHandler_GetMoniker, 1979 DefaultHandler_InitFromData, 1980 DefaultHandler_GetClipboardData, 1981 DefaultHandler_DoVerb, 1982 DefaultHandler_EnumVerbs, 1983 DefaultHandler_Update, 1984 DefaultHandler_IsUpToDate, 1985 DefaultHandler_GetUserClassID, 1986 DefaultHandler_GetUserType, 1987 DefaultHandler_SetExtent, 1988 DefaultHandler_GetExtent, 1989 DefaultHandler_Advise, 1990 DefaultHandler_Unadvise, 1991 DefaultHandler_EnumAdvise, 1992 DefaultHandler_GetMiscStatus, 1993 DefaultHandler_SetColorScheme 1994 }; 1995 1996 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable = 1997 { 1998 DefaultHandler_NDIUnknown_QueryInterface, 1999 DefaultHandler_NDIUnknown_AddRef, 2000 DefaultHandler_NDIUnknown_Release, 2001 }; 2002 2003 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable = 2004 { 2005 DefaultHandler_IDataObject_QueryInterface, 2006 DefaultHandler_IDataObject_AddRef, 2007 DefaultHandler_IDataObject_Release, 2008 DefaultHandler_GetData, 2009 DefaultHandler_GetDataHere, 2010 DefaultHandler_QueryGetData, 2011 DefaultHandler_GetCanonicalFormatEtc, 2012 DefaultHandler_SetData, 2013 DefaultHandler_EnumFormatEtc, 2014 DefaultHandler_DAdvise, 2015 DefaultHandler_DUnadvise, 2016 DefaultHandler_EnumDAdvise 2017 }; 2018 2019 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable = 2020 { 2021 DefaultHandler_IRunnableObject_QueryInterface, 2022 DefaultHandler_IRunnableObject_AddRef, 2023 DefaultHandler_IRunnableObject_Release, 2024 DefaultHandler_GetRunningClass, 2025 DefaultHandler_Run, 2026 DefaultHandler_IsRunning, 2027 DefaultHandler_LockRunning, 2028 DefaultHandler_SetContainedObject 2029 }; 2030 2031 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable = 2032 { 2033 DefaultHandler_IAdviseSink_QueryInterface, 2034 DefaultHandler_IAdviseSink_AddRef, 2035 DefaultHandler_IAdviseSink_Release, 2036 DefaultHandler_IAdviseSink_OnDataChange, 2037 DefaultHandler_IAdviseSink_OnViewChange, 2038 DefaultHandler_IAdviseSink_OnRename, 2039 DefaultHandler_IAdviseSink_OnSave, 2040 DefaultHandler_IAdviseSink_OnClose 2041 }; 2042 2043 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable = 2044 { 2045 DefaultHandler_IPersistStorage_QueryInterface, 2046 DefaultHandler_IPersistStorage_AddRef, 2047 DefaultHandler_IPersistStorage_Release, 2048 DefaultHandler_IPersistStorage_GetClassID, 2049 DefaultHandler_IPersistStorage_IsDirty, 2050 DefaultHandler_IPersistStorage_InitNew, 2051 DefaultHandler_IPersistStorage_Load, 2052 DefaultHandler_IPersistStorage_Save, 2053 DefaultHandler_IPersistStorage_SaveCompleted, 2054 DefaultHandler_IPersistStorage_HandsOffStorage 2055 }; 2056 2057 /********************************************************* 2058 * Methods implementation for the DefaultHandler class. 2059 */ 2060 static DefaultHandler* DefaultHandler_Construct( 2061 REFCLSID clsid, 2062 LPUNKNOWN pUnkOuter, 2063 DWORD flags, 2064 IClassFactory *pCF) 2065 { 2066 DefaultHandler* This = NULL; 2067 HRESULT hr; 2068 2069 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler)); 2070 2071 if (!This) 2072 return This; 2073 2074 This->IOleObject_iface.lpVtbl = &DefaultHandler_IOleObject_VTable; 2075 This->IUnknown_iface.lpVtbl = &DefaultHandler_NDIUnknown_VTable; 2076 This->IDataObject_iface.lpVtbl = &DefaultHandler_IDataObject_VTable; 2077 This->IRunnableObject_iface.lpVtbl = &DefaultHandler_IRunnableObject_VTable; 2078 This->IAdviseSink_iface.lpVtbl = &DefaultHandler_IAdviseSink_VTable; 2079 This->IPersistStorage_iface.lpVtbl = &DefaultHandler_IPersistStorage_VTable; 2080 2081 This->inproc_server = (flags & EMBDHLP_INPROC_SERVER) != 0; 2082 2083 /* 2084 * Start with one reference count. The caller of this function 2085 * must release the interface pointer when it is done. 2086 */ 2087 This->ref = 1; 2088 2089 /* 2090 * Initialize the outer unknown 2091 * We don't keep a reference on the outer unknown since, the way 2092 * aggregation works, our lifetime is at least as large as its 2093 * lifetime. 2094 */ 2095 if (!pUnkOuter) 2096 pUnkOuter = &This->IUnknown_iface; 2097 2098 This->outerUnknown = pUnkOuter; 2099 2100 /* 2101 * Create a datacache object. 2102 * We aggregate with the datacache. Make sure we pass our outer 2103 * unknown as the datacache's outer unknown. 2104 */ 2105 hr = CreateDataCache(This->outerUnknown, 2106 clsid, 2107 &IID_IUnknown, 2108 (void**)&This->dataCache); 2109 if(SUCCEEDED(hr)) 2110 { 2111 hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg); 2112 /* keeping a reference to This->dataCache_PersistStg causes us to keep a 2113 * reference on the outer object */ 2114 if (SUCCEEDED(hr)) 2115 IUnknown_Release(This->outerUnknown); 2116 else 2117 IUnknown_Release(This->dataCache); 2118 } 2119 if(FAILED(hr)) 2120 { 2121 ERR("Unexpected error creating data cache\n"); 2122 HeapFree(GetProcessHeap(), 0, This); 2123 return NULL; 2124 } 2125 2126 This->clsid = *clsid; 2127 This->clientSite = NULL; 2128 This->oleAdviseHolder = NULL; 2129 This->dataAdviseHolder = NULL; 2130 This->containerApp = NULL; 2131 This->containerObj = NULL; 2132 This->pOleDelegate = NULL; 2133 This->pPSDelegate = NULL; 2134 This->pDataDelegate = NULL; 2135 This->object_state = object_state_not_running; 2136 This->in_call = 0; 2137 2138 This->dwAdvConn = 0; 2139 This->storage = NULL; 2140 This->storage_state = storage_state_uninitialised; 2141 2142 if (This->inproc_server && !(flags & EMBDHLP_DELAYCREATE)) 2143 { 2144 HRESULT hr; 2145 This->pCFObject = NULL; 2146 if (pCF) 2147 hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IOleObject, (void **)&This->pOleDelegate); 2148 else 2149 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER, 2150 &IID_IOleObject, (void **)&This->pOleDelegate); 2151 if (SUCCEEDED(hr)) 2152 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate); 2153 if (SUCCEEDED(hr)) 2154 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&This->pDataDelegate); 2155 if (SUCCEEDED(hr)) 2156 This->object_state = object_state_running; 2157 if (FAILED(hr)) 2158 WARN("object creation failed with error %08x\n", hr); 2159 } 2160 else 2161 { 2162 This->pCFObject = pCF; 2163 if (pCF) IClassFactory_AddRef(pCF); 2164 } 2165 2166 return This; 2167 } 2168 2169 static void DefaultHandler_Destroy( 2170 DefaultHandler* This) 2171 { 2172 TRACE("(%p)\n", This); 2173 2174 /* AddRef/Release may be called on this object during destruction. 2175 * Prevent the object being destroyed recursively by artificially raising 2176 * the reference count. */ 2177 This->ref = 10000; 2178 2179 /* release delegates */ 2180 DefaultHandler_Stop(This); 2181 2182 HeapFree( GetProcessHeap(), 0, This->containerApp ); 2183 This->containerApp = NULL; 2184 HeapFree( GetProcessHeap(), 0, This->containerObj ); 2185 This->containerObj = NULL; 2186 2187 if (This->dataCache) 2188 { 2189 /* to balance out the release of dataCache_PersistStg which will result 2190 * in a reference being released from the outer unknown */ 2191 IUnknown_AddRef(This->outerUnknown); 2192 IPersistStorage_Release(This->dataCache_PersistStg); 2193 IUnknown_Release(This->dataCache); 2194 This->dataCache_PersistStg = NULL; 2195 This->dataCache = NULL; 2196 } 2197 2198 if (This->clientSite) 2199 { 2200 IOleClientSite_Release(This->clientSite); 2201 This->clientSite = NULL; 2202 } 2203 2204 if (This->oleAdviseHolder) 2205 { 2206 IOleAdviseHolder_Release(This->oleAdviseHolder); 2207 This->oleAdviseHolder = NULL; 2208 } 2209 2210 if (This->dataAdviseHolder) 2211 { 2212 IDataAdviseHolder_Release(This->dataAdviseHolder); 2213 This->dataAdviseHolder = NULL; 2214 } 2215 2216 if (This->storage) 2217 { 2218 IStorage_Release(This->storage); 2219 This->storage = NULL; 2220 } 2221 2222 if (This->pCFObject) 2223 { 2224 IClassFactory_Release(This->pCFObject); 2225 This->pCFObject = NULL; 2226 } 2227 2228 HeapFree(GetProcessHeap(), 0, This); 2229 } 2230 2231 /****************************************************************************** 2232 * OleCreateEmbeddingHelper [OLE32.@] 2233 */ 2234 HRESULT WINAPI OleCreateEmbeddingHelper( 2235 REFCLSID clsid, 2236 LPUNKNOWN pUnkOuter, 2237 DWORD flags, 2238 IClassFactory *pCF, 2239 REFIID riid, 2240 LPVOID* ppvObj) 2241 { 2242 DefaultHandler* newHandler = NULL; 2243 HRESULT hr = S_OK; 2244 2245 TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, flags, pCF, debugstr_guid(riid), ppvObj); 2246 2247 if (!ppvObj) 2248 return E_POINTER; 2249 2250 *ppvObj = NULL; 2251 2252 /* 2253 * If This handler is constructed for aggregation, make sure 2254 * the caller is requesting the IUnknown interface. 2255 * This is necessary because it's the only time the non-delegating 2256 * IUnknown pointer can be returned to the outside. 2257 */ 2258 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid)) 2259 return CLASS_E_NOAGGREGATION; 2260 2261 /* 2262 * Try to construct a new instance of the class. 2263 */ 2264 newHandler = DefaultHandler_Construct(clsid, pUnkOuter, flags, pCF); 2265 2266 if (!newHandler) 2267 return E_OUTOFMEMORY; 2268 2269 /* 2270 * Make sure it supports the interface required by the caller. 2271 */ 2272 hr = IUnknown_QueryInterface(&newHandler->IUnknown_iface, riid, ppvObj); 2273 2274 /* 2275 * Release the reference obtained in the constructor. If 2276 * the QueryInterface was unsuccessful, it will free the class. 2277 */ 2278 IUnknown_Release(&newHandler->IUnknown_iface); 2279 2280 return hr; 2281 } 2282 2283 2284 /****************************************************************************** 2285 * OleCreateDefaultHandler [OLE32.@] 2286 */ 2287 HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter, 2288 REFIID riid, LPVOID* ppvObj) 2289 { 2290 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter,debugstr_guid(riid), ppvObj); 2291 return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW, 2292 NULL, riid, ppvObj); 2293 } 2294 2295 typedef struct HandlerCF 2296 { 2297 IClassFactory IClassFactory_iface; 2298 LONG refs; 2299 CLSID clsid; 2300 } HandlerCF; 2301 2302 static inline HandlerCF *impl_from_IClassFactory(IClassFactory *iface) 2303 { 2304 return CONTAINING_RECORD(iface, HandlerCF, IClassFactory_iface); 2305 } 2306 2307 static HRESULT WINAPI 2308 HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv) 2309 { 2310 *ppv = NULL; 2311 if (IsEqualIID(riid,&IID_IUnknown) || 2312 IsEqualIID(riid,&IID_IClassFactory)) 2313 { 2314 *ppv = iface; 2315 IClassFactory_AddRef(iface); 2316 return S_OK; 2317 } 2318 return E_NOINTERFACE; 2319 } 2320 2321 static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface) 2322 { 2323 HandlerCF *This = impl_from_IClassFactory(iface); 2324 return InterlockedIncrement(&This->refs); 2325 } 2326 2327 static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface) 2328 { 2329 HandlerCF *This = impl_from_IClassFactory(iface); 2330 ULONG refs = InterlockedDecrement(&This->refs); 2331 if (!refs) 2332 HeapFree(GetProcessHeap(), 0, This); 2333 return refs; 2334 } 2335 2336 static HRESULT WINAPI 2337 HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk, 2338 REFIID riid, LPVOID *ppv) 2339 { 2340 HandlerCF *This = impl_from_IClassFactory(iface); 2341 return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv); 2342 } 2343 2344 static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) 2345 { 2346 FIXME("(%d), stub!\n",fLock); 2347 return S_OK; 2348 } 2349 2350 static const IClassFactoryVtbl HandlerClassFactoryVtbl = { 2351 HandlerCF_QueryInterface, 2352 HandlerCF_AddRef, 2353 HandlerCF_Release, 2354 HandlerCF_CreateInstance, 2355 HandlerCF_LockServer 2356 }; 2357 2358 HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv) 2359 { 2360 HRESULT hr; 2361 HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); 2362 if (!This) return E_OUTOFMEMORY; 2363 This->IClassFactory_iface.lpVtbl = &HandlerClassFactoryVtbl; 2364 This->refs = 0; 2365 This->clsid = *rclsid; 2366 2367 hr = IClassFactory_QueryInterface(&This->IClassFactory_iface, riid, ppv); 2368 if (FAILED(hr)) 2369 HeapFree(GetProcessHeap(), 0, This); 2370 2371 return hr; 2372 } 2373