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