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