Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendefaulthandler.c
Go to the documentation of this file.
00001 /* 00002 * OLE 2 default object handler 00003 * 00004 * Copyright 1999 Francis Beaudet 00005 * Copyright 2000 Abey George 00006 * 00007 * This library is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * This library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with this library; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00020 * 00021 * NOTES: 00022 * The OLE2 default object handler supports a whole whack of 00023 * interfaces including: 00024 * IOleObject, IDataObject, IPersistStorage, IViewObject2, 00025 * IRunnableObject, IOleCache2, IOleCacheControl and much more. 00026 * 00027 * All the implementation details are taken from: Inside OLE 00028 * second edition by Kraig Brockschmidt, 00029 * 00030 * TODO 00031 * - This implementation of the default handler does not launch the 00032 * server in the DoVerb, Update, GetData, GetDataHere and Run 00033 * methods. When it is fixed to do so, all the methods will have 00034 * to be revisited to allow delegating to the running object 00035 * 00036 * - All methods in the class that use the class ID should be 00037 * aware that it is possible for a class to be treated as 00038 * another one and go into emulation mode. Nothing has been 00039 * done in this area. 00040 * 00041 * - Some functions still return E_NOTIMPL they have to be 00042 * implemented. Most of those are related to the running of the 00043 * actual server. 00044 * 00045 * - All the methods related to notification and advise sinks are 00046 * in place but no notifications are sent to the sinks yet. 00047 */ 00048 #include <assert.h> 00049 #include <stdarg.h> 00050 #include <string.h> 00051 00052 #define COBJMACROS 00053 00054 #include "windef.h" 00055 #include "winbase.h" 00056 #include "winuser.h" 00057 #include "winerror.h" 00058 #include "ole2.h" 00059 00060 #include "compobj_private.h" 00061 00062 #include "wine/unicode.h" 00063 #include "wine/debug.h" 00064 00065 WINE_DEFAULT_DEBUG_CHANNEL(ole); 00066 00067 enum storage_state 00068 { 00069 storage_state_uninitialised, 00070 storage_state_initialised, 00071 storage_state_loaded 00072 }; 00073 00074 enum object_state 00075 { 00076 object_state_not_running, 00077 object_state_running 00078 }; 00079 00080 /**************************************************************************** 00081 * DefaultHandler 00082 * 00083 */ 00084 struct DefaultHandler 00085 { 00086 IOleObject IOleObject_iface; 00087 IUnknown IUnknown_iface; 00088 IDataObject IDataObject_iface; 00089 IRunnableObject IRunnableObject_iface; 00090 IAdviseSink IAdviseSink_iface; 00091 IPersistStorage IPersistStorage_iface; 00092 00093 /* Reference count of this object */ 00094 LONG ref; 00095 00096 /* IUnknown implementation of the outer object. */ 00097 IUnknown* outerUnknown; 00098 00099 /* Class Id that this handler object represents. */ 00100 CLSID clsid; 00101 00102 /* IUnknown implementation of the datacache. */ 00103 IUnknown* dataCache; 00104 /* IPersistStorage implementation of the datacache. */ 00105 IPersistStorage* dataCache_PersistStg; 00106 00107 /* Client site for the embedded object. */ 00108 IOleClientSite* clientSite; 00109 00110 /* 00111 * The IOleAdviseHolder maintains the connections 00112 * on behalf of the default handler. 00113 */ 00114 IOleAdviseHolder* oleAdviseHolder; 00115 00116 /* 00117 * The IDataAdviseHolder maintains the data 00118 * connections on behalf of the default handler. 00119 */ 00120 IDataAdviseHolder* dataAdviseHolder; 00121 00122 /* Name of the container and object contained */ 00123 LPWSTR containerApp; 00124 LPWSTR containerObj; 00125 00126 /* IOleObject delegate */ 00127 IOleObject *pOleDelegate; 00128 /* IPersistStorage delegate */ 00129 IPersistStorage *pPSDelegate; 00130 /* IDataObject delegate */ 00131 IDataObject *pDataDelegate; 00132 enum object_state object_state; 00133 00134 /* connection cookie for the advise on the delegate OLE object */ 00135 DWORD dwAdvConn; 00136 00137 /* storage passed to Load or InitNew */ 00138 IStorage *storage; 00139 enum storage_state storage_state; 00140 00141 /* optional class factory for object */ 00142 IClassFactory *pCFObject; 00143 /* TRUE if acting as an inproc server instead of an inproc handler */ 00144 BOOL inproc_server; 00145 }; 00146 00147 typedef struct DefaultHandler DefaultHandler; 00148 00149 static inline DefaultHandler *impl_from_IOleObject( IOleObject *iface ) 00150 { 00151 return CONTAINING_RECORD(iface, DefaultHandler, IOleObject_iface); 00152 } 00153 00154 static inline DefaultHandler *impl_from_IUnknown( IUnknown *iface ) 00155 { 00156 return CONTAINING_RECORD(iface, DefaultHandler, IUnknown_iface); 00157 } 00158 00159 static inline DefaultHandler *impl_from_IDataObject( IDataObject *iface ) 00160 { 00161 return CONTAINING_RECORD(iface, DefaultHandler, IDataObject_iface); 00162 } 00163 00164 static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface ) 00165 { 00166 return CONTAINING_RECORD(iface, DefaultHandler, IRunnableObject_iface); 00167 } 00168 00169 static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface ) 00170 { 00171 return CONTAINING_RECORD(iface, DefaultHandler, IAdviseSink_iface); 00172 } 00173 00174 static inline DefaultHandler *impl_from_IPersistStorage( IPersistStorage *iface ) 00175 { 00176 return CONTAINING_RECORD(iface, DefaultHandler, IPersistStorage_iface); 00177 } 00178 00179 static void DefaultHandler_Destroy(DefaultHandler* This); 00180 00181 static inline BOOL object_is_running(DefaultHandler *This) 00182 { 00183 return IRunnableObject_IsRunning(&This->IRunnableObject_iface); 00184 } 00185 00186 /********************************************************* 00187 * Method implementation for the non delegating IUnknown 00188 * part of the DefaultHandler class. 00189 */ 00190 00191 /************************************************************************ 00192 * DefaultHandler_NDIUnknown_QueryInterface (IUnknown) 00193 * 00194 * See Windows documentation for more details on IUnknown methods. 00195 * 00196 * This version of QueryInterface will not delegate its implementation 00197 * to the outer unknown. 00198 */ 00199 static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface( 00200 IUnknown* iface, 00201 REFIID riid, 00202 void** ppvObject) 00203 { 00204 DefaultHandler *This = impl_from_IUnknown(iface); 00205 00206 if (!ppvObject) 00207 return E_INVALIDARG; 00208 00209 *ppvObject = NULL; 00210 00211 if (IsEqualIID(&IID_IUnknown, riid)) 00212 *ppvObject = iface; 00213 else if (IsEqualIID(&IID_IOleObject, riid)) 00214 *ppvObject = &This->IOleObject_iface; 00215 else if (IsEqualIID(&IID_IDataObject, riid)) 00216 *ppvObject = &This->IDataObject_iface; 00217 else if (IsEqualIID(&IID_IRunnableObject, riid)) 00218 *ppvObject = &This->IRunnableObject_iface; 00219 else if (IsEqualIID(&IID_IPersist, riid) || 00220 IsEqualIID(&IID_IPersistStorage, riid)) 00221 *ppvObject = &This->IPersistStorage_iface; 00222 else if (IsEqualIID(&IID_IViewObject, riid) || 00223 IsEqualIID(&IID_IViewObject2, riid) || 00224 IsEqualIID(&IID_IOleCache, riid) || 00225 IsEqualIID(&IID_IOleCache2, riid)) 00226 { 00227 HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject); 00228 if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid)); 00229 return hr; 00230 } 00231 else if (This->inproc_server && This->pOleDelegate) 00232 { 00233 return IUnknown_QueryInterface(This->pOleDelegate, riid, ppvObject); 00234 } 00235 00236 /* Check that we obtained an interface. */ 00237 if (*ppvObject == NULL) 00238 { 00239 WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid)); 00240 return E_NOINTERFACE; 00241 } 00242 00243 /* 00244 * Query Interface always increases the reference count by one when it is 00245 * successful. 00246 */ 00247 IUnknown_AddRef((IUnknown*)*ppvObject); 00248 00249 return S_OK; 00250 } 00251 00252 /************************************************************************ 00253 * DefaultHandler_NDIUnknown_AddRef (IUnknown) 00254 * 00255 * See Windows documentation for more details on IUnknown methods. 00256 * 00257 * This version of QueryInterface will not delegate its implementation 00258 * to the outer unknown. 00259 */ 00260 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef( 00261 IUnknown* iface) 00262 { 00263 DefaultHandler *This = impl_from_IUnknown(iface); 00264 return InterlockedIncrement(&This->ref); 00265 } 00266 00267 /************************************************************************ 00268 * DefaultHandler_NDIUnknown_Release (IUnknown) 00269 * 00270 * See Windows documentation for more details on IUnknown methods. 00271 * 00272 * This version of QueryInterface will not delegate its implementation 00273 * to the outer unknown. 00274 */ 00275 static ULONG WINAPI DefaultHandler_NDIUnknown_Release( 00276 IUnknown* iface) 00277 { 00278 DefaultHandler *This = impl_from_IUnknown(iface); 00279 ULONG ref; 00280 00281 ref = InterlockedDecrement(&This->ref); 00282 00283 if (!ref) DefaultHandler_Destroy(This); 00284 00285 return ref; 00286 } 00287 00288 /********************************************************* 00289 * Methods implementation for the IOleObject part of 00290 * the DefaultHandler class. 00291 */ 00292 00293 /************************************************************************ 00294 * DefaultHandler_QueryInterface (IUnknown) 00295 * 00296 * See Windows documentation for more details on IUnknown methods. 00297 */ 00298 static HRESULT WINAPI DefaultHandler_QueryInterface( 00299 IOleObject* iface, 00300 REFIID riid, 00301 void** ppvObject) 00302 { 00303 DefaultHandler *This = impl_from_IOleObject(iface); 00304 00305 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject); 00306 } 00307 00308 /************************************************************************ 00309 * DefaultHandler_AddRef (IUnknown) 00310 * 00311 * See Windows documentation for more details on IUnknown methods. 00312 */ 00313 static ULONG WINAPI DefaultHandler_AddRef( 00314 IOleObject* iface) 00315 { 00316 DefaultHandler *This = impl_from_IOleObject(iface); 00317 00318 return IUnknown_AddRef(This->outerUnknown); 00319 } 00320 00321 /************************************************************************ 00322 * DefaultHandler_Release (IUnknown) 00323 * 00324 * See Windows documentation for more details on IUnknown methods. 00325 */ 00326 static ULONG WINAPI DefaultHandler_Release( 00327 IOleObject* iface) 00328 { 00329 DefaultHandler *This = impl_from_IOleObject(iface); 00330 00331 return IUnknown_Release(This->outerUnknown); 00332 } 00333 00334 /************************************************************************ 00335 * DefaultHandler_SetClientSite (IOleObject) 00336 * 00337 * The default handler's implementation of this method only keeps the 00338 * client site pointer for future reference. 00339 * 00340 * See Windows documentation for more details on IOleObject methods. 00341 */ 00342 static HRESULT WINAPI DefaultHandler_SetClientSite( 00343 IOleObject* iface, 00344 IOleClientSite* pClientSite) 00345 { 00346 DefaultHandler *This = impl_from_IOleObject(iface); 00347 HRESULT hr = S_OK; 00348 00349 TRACE("(%p, %p)\n", iface, pClientSite); 00350 00351 if (object_is_running(This)) 00352 hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite); 00353 00354 /* 00355 * Make sure we release the previous client site if there 00356 * was one. 00357 */ 00358 if (This->clientSite) 00359 IOleClientSite_Release(This->clientSite); 00360 00361 This->clientSite = pClientSite; 00362 00363 if (This->clientSite) 00364 IOleClientSite_AddRef(This->clientSite); 00365 00366 return hr; 00367 } 00368 00369 /************************************************************************ 00370 * DefaultHandler_GetClientSite (IOleObject) 00371 * 00372 * The default handler's implementation of this method returns the 00373 * last pointer set in IOleObject_SetClientSite. 00374 * 00375 * See Windows documentation for more details on IOleObject methods. 00376 */ 00377 static HRESULT WINAPI DefaultHandler_GetClientSite( 00378 IOleObject* iface, 00379 IOleClientSite** ppClientSite) 00380 { 00381 DefaultHandler *This = impl_from_IOleObject(iface); 00382 00383 if (!ppClientSite) 00384 return E_POINTER; 00385 00386 *ppClientSite = This->clientSite; 00387 00388 if (This->clientSite) 00389 IOleClientSite_AddRef(This->clientSite); 00390 00391 return S_OK; 00392 } 00393 00394 /************************************************************************ 00395 * DefaultHandler_SetHostNames (IOleObject) 00396 * 00397 * The default handler's implementation of this method just stores 00398 * the strings and returns S_OK. 00399 * 00400 * See Windows documentation for more details on IOleObject methods. 00401 */ 00402 static HRESULT WINAPI DefaultHandler_SetHostNames( 00403 IOleObject* iface, 00404 LPCOLESTR szContainerApp, 00405 LPCOLESTR szContainerObj) 00406 { 00407 DefaultHandler *This = impl_from_IOleObject(iface); 00408 00409 TRACE("(%p, %s, %s)\n", 00410 iface, 00411 debugstr_w(szContainerApp), 00412 debugstr_w(szContainerObj)); 00413 00414 if (object_is_running(This)) 00415 IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj); 00416 00417 /* Be sure to cleanup before re-assigning the strings. */ 00418 HeapFree( GetProcessHeap(), 0, This->containerApp ); 00419 This->containerApp = NULL; 00420 HeapFree( GetProcessHeap(), 0, This->containerObj ); 00421 This->containerObj = NULL; 00422 00423 if (szContainerApp) 00424 { 00425 if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0, 00426 (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) ))) 00427 strcpyW( This->containerApp, szContainerApp ); 00428 } 00429 00430 if (szContainerObj) 00431 { 00432 if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0, 00433 (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) ))) 00434 strcpyW( This->containerObj, szContainerObj ); 00435 } 00436 return S_OK; 00437 } 00438 00439 static void release_delegates(DefaultHandler *This) 00440 { 00441 if (This->pDataDelegate) 00442 { 00443 IDataObject_Release(This->pDataDelegate); 00444 This->pDataDelegate = NULL; 00445 } 00446 if (This->pPSDelegate) 00447 { 00448 IPersistStorage_Release(This->pPSDelegate); 00449 This->pPSDelegate = NULL; 00450 } 00451 if (This->pOleDelegate) 00452 { 00453 IOleObject_Release(This->pOleDelegate); 00454 This->pOleDelegate = NULL; 00455 } 00456 } 00457 00458 /* undoes the work done by DefaultHandler_Run */ 00459 static void DefaultHandler_Stop(DefaultHandler *This) 00460 { 00461 if (!object_is_running(This)) 00462 return; 00463 00464 IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn); 00465 00466 /* FIXME: call IOleCache_OnStop */ 00467 00468 if (This->dataAdviseHolder) 00469 DataAdviseHolder_OnDisconnect(This->dataAdviseHolder); 00470 00471 This->object_state = object_state_not_running; 00472 } 00473 00474 /************************************************************************ 00475 * DefaultHandler_Close (IOleObject) 00476 * 00477 * The default handler's implementation of this method is meaningless 00478 * without a running server so it does nothing. 00479 * 00480 * See Windows documentation for more details on IOleObject methods. 00481 */ 00482 static HRESULT WINAPI DefaultHandler_Close( 00483 IOleObject* iface, 00484 DWORD dwSaveOption) 00485 { 00486 DefaultHandler *This = impl_from_IOleObject(iface); 00487 HRESULT hr; 00488 00489 TRACE("(%d)\n", dwSaveOption); 00490 00491 if (!object_is_running(This)) 00492 return S_OK; 00493 00494 hr = IOleObject_Close(This->pOleDelegate, dwSaveOption); 00495 00496 DefaultHandler_Stop(This); 00497 release_delegates(This); 00498 00499 return hr; 00500 } 00501 00502 /************************************************************************ 00503 * DefaultHandler_SetMoniker (IOleObject) 00504 * 00505 * The default handler's implementation of this method does nothing. 00506 * 00507 * See Windows documentation for more details on IOleObject methods. 00508 */ 00509 static HRESULT WINAPI DefaultHandler_SetMoniker( 00510 IOleObject* iface, 00511 DWORD dwWhichMoniker, 00512 IMoniker* pmk) 00513 { 00514 DefaultHandler *This = impl_from_IOleObject(iface); 00515 00516 TRACE("(%p, %d, %p)\n", 00517 iface, 00518 dwWhichMoniker, 00519 pmk); 00520 00521 if (object_is_running(This)) 00522 return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk); 00523 00524 return S_OK; 00525 } 00526 00527 /************************************************************************ 00528 * DefaultHandler_GetMoniker (IOleObject) 00529 * 00530 * Delegate this request to the client site if we have one. 00531 * 00532 * See Windows documentation for more details on IOleObject methods. 00533 */ 00534 static HRESULT WINAPI DefaultHandler_GetMoniker( 00535 IOleObject* iface, 00536 DWORD dwAssign, 00537 DWORD dwWhichMoniker, 00538 IMoniker** ppmk) 00539 { 00540 DefaultHandler *This = impl_from_IOleObject(iface); 00541 00542 TRACE("(%p, %d, %d, %p)\n", 00543 iface, dwAssign, dwWhichMoniker, ppmk); 00544 00545 if (object_is_running(This)) 00546 return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker, 00547 ppmk); 00548 00549 /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */ 00550 if (This->clientSite) 00551 { 00552 return IOleClientSite_GetMoniker(This->clientSite, 00553 dwAssign, 00554 dwWhichMoniker, 00555 ppmk); 00556 00557 } 00558 00559 return E_FAIL; 00560 } 00561 00562 /************************************************************************ 00563 * DefaultHandler_InitFromData (IOleObject) 00564 * 00565 * This method is meaningless if the server is not running 00566 * 00567 * See Windows documentation for more details on IOleObject methods. 00568 */ 00569 static HRESULT WINAPI DefaultHandler_InitFromData( 00570 IOleObject* iface, 00571 IDataObject* pDataObject, 00572 BOOL fCreation, 00573 DWORD dwReserved) 00574 { 00575 DefaultHandler *This = impl_from_IOleObject(iface); 00576 00577 TRACE("(%p, %p, %d, %d)\n", 00578 iface, pDataObject, fCreation, dwReserved); 00579 00580 if (object_is_running(This)) 00581 return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation, 00582 dwReserved); 00583 return OLE_E_NOTRUNNING; 00584 } 00585 00586 /************************************************************************ 00587 * DefaultHandler_GetClipboardData (IOleObject) 00588 * 00589 * This method is meaningless if the server is not running 00590 * 00591 * See Windows documentation for more details on IOleObject methods. 00592 */ 00593 static HRESULT WINAPI DefaultHandler_GetClipboardData( 00594 IOleObject* iface, 00595 DWORD dwReserved, 00596 IDataObject** ppDataObject) 00597 { 00598 DefaultHandler *This = impl_from_IOleObject(iface); 00599 00600 TRACE("(%p, %d, %p)\n", 00601 iface, dwReserved, ppDataObject); 00602 00603 if (object_is_running(This)) 00604 return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved, 00605 ppDataObject); 00606 00607 return OLE_E_NOTRUNNING; 00608 } 00609 00610 static HRESULT WINAPI DefaultHandler_DoVerb( 00611 IOleObject* iface, 00612 LONG iVerb, 00613 struct tagMSG* lpmsg, 00614 IOleClientSite* pActiveSite, 00615 LONG lindex, 00616 HWND hwndParent, 00617 LPCRECT lprcPosRect) 00618 { 00619 DefaultHandler *This = impl_from_IOleObject(iface); 00620 IRunnableObject *pRunnableObj = &This->IRunnableObject_iface; 00621 HRESULT hr; 00622 00623 TRACE("(%d, %p, %p, %d, %p, %s)\n", iVerb, lpmsg, pActiveSite, lindex, hwndParent, wine_dbgstr_rect(lprcPosRect)); 00624 00625 hr = IRunnableObject_Run(pRunnableObj, NULL); 00626 if (FAILED(hr)) return hr; 00627 00628 return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite, 00629 lindex, hwndParent, lprcPosRect); 00630 } 00631 00632 /************************************************************************ 00633 * DefaultHandler_EnumVerbs (IOleObject) 00634 * 00635 * The default handler implementation of this method simply delegates 00636 * to OleRegEnumVerbs 00637 * 00638 * See Windows documentation for more details on IOleObject methods. 00639 */ 00640 static HRESULT WINAPI DefaultHandler_EnumVerbs( 00641 IOleObject* iface, 00642 IEnumOLEVERB** ppEnumOleVerb) 00643 { 00644 DefaultHandler *This = impl_from_IOleObject(iface); 00645 HRESULT hr = OLE_S_USEREG; 00646 00647 TRACE("(%p, %p)\n", iface, ppEnumOleVerb); 00648 00649 if (object_is_running(This)) 00650 hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb); 00651 00652 if (hr == OLE_S_USEREG) 00653 return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb); 00654 else 00655 return hr; 00656 } 00657 00658 static HRESULT WINAPI DefaultHandler_Update( 00659 IOleObject* iface) 00660 { 00661 DefaultHandler *This = impl_from_IOleObject(iface); 00662 TRACE("(%p)\n", iface); 00663 00664 if (!object_is_running(This)) 00665 { 00666 FIXME("Should run object\n"); 00667 return E_NOTIMPL; 00668 } 00669 return IOleObject_Update(This->pOleDelegate); 00670 } 00671 00672 /************************************************************************ 00673 * DefaultHandler_IsUpToDate (IOleObject) 00674 * 00675 * This method is meaningless if the server is not running 00676 * 00677 * See Windows documentation for more details on IOleObject methods. 00678 */ 00679 static HRESULT WINAPI DefaultHandler_IsUpToDate( 00680 IOleObject* iface) 00681 { 00682 DefaultHandler *This = impl_from_IOleObject(iface); 00683 TRACE("(%p)\n", iface); 00684 00685 if (object_is_running(This)) 00686 return IOleObject_IsUpToDate(This->pOleDelegate); 00687 00688 return OLE_E_NOTRUNNING; 00689 } 00690 00691 /************************************************************************ 00692 * DefaultHandler_GetUserClassID (IOleObject) 00693 * 00694 * TODO: Map to a new class ID if emulation is active. 00695 * 00696 * See Windows documentation for more details on IOleObject methods. 00697 */ 00698 static HRESULT WINAPI DefaultHandler_GetUserClassID( 00699 IOleObject* iface, 00700 CLSID* pClsid) 00701 { 00702 DefaultHandler *This = impl_from_IOleObject(iface); 00703 00704 TRACE("(%p, %p)\n", iface, pClsid); 00705 00706 if (object_is_running(This)) 00707 return IOleObject_GetUserClassID(This->pOleDelegate, pClsid); 00708 00709 if (!pClsid) 00710 return E_POINTER; 00711 00712 *pClsid = This->clsid; 00713 00714 return S_OK; 00715 } 00716 00717 /************************************************************************ 00718 * DefaultHandler_GetUserType (IOleObject) 00719 * 00720 * The default handler implementation of this method simply delegates 00721 * to OleRegGetUserType 00722 * 00723 * See Windows documentation for more details on IOleObject methods. 00724 */ 00725 static HRESULT WINAPI DefaultHandler_GetUserType( 00726 IOleObject* iface, 00727 DWORD dwFormOfType, 00728 LPOLESTR* pszUserType) 00729 { 00730 DefaultHandler *This = impl_from_IOleObject(iface); 00731 00732 TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType); 00733 if (object_is_running(This)) 00734 return IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType); 00735 00736 return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType); 00737 } 00738 00739 /************************************************************************ 00740 * DefaultHandler_SetExtent (IOleObject) 00741 * 00742 * This method is meaningless if the server is not running 00743 * 00744 * See Windows documentation for more details on IOleObject methods. 00745 */ 00746 static HRESULT WINAPI DefaultHandler_SetExtent( 00747 IOleObject* iface, 00748 DWORD dwDrawAspect, 00749 SIZEL* psizel) 00750 { 00751 DefaultHandler *This = impl_from_IOleObject(iface); 00752 00753 TRACE("(%p, %x, (%d x %d))\n", iface, 00754 dwDrawAspect, psizel->cx, psizel->cy); 00755 00756 if (object_is_running(This)) 00757 return IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel); 00758 00759 return OLE_E_NOTRUNNING; 00760 } 00761 00762 /************************************************************************ 00763 * DefaultHandler_GetExtent (IOleObject) 00764 * 00765 * The default handler's implementation of this method returns uses 00766 * the cache to locate the aspect and extract the extent from it. 00767 * 00768 * See Windows documentation for more details on IOleObject methods. 00769 */ 00770 static HRESULT WINAPI DefaultHandler_GetExtent( 00771 IOleObject* iface, 00772 DWORD dwDrawAspect, 00773 SIZEL* psizel) 00774 { 00775 DVTARGETDEVICE* targetDevice; 00776 IViewObject2* cacheView = NULL; 00777 HRESULT hres; 00778 00779 DefaultHandler *This = impl_from_IOleObject(iface); 00780 00781 TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel); 00782 00783 if (object_is_running(This)) 00784 return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel); 00785 00786 hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView); 00787 if (FAILED(hres)) 00788 return E_UNEXPECTED; 00789 00790 /* 00791 * Prepare the call to the cache's GetExtent method. 00792 * 00793 * Here we would build a valid DVTARGETDEVICE structure 00794 * but, since we are calling into the data cache, we 00795 * know its implementation and we'll skip this 00796 * extra work until later. 00797 */ 00798 targetDevice = NULL; 00799 00800 hres = IViewObject2_GetExtent(cacheView, 00801 dwDrawAspect, 00802 -1, 00803 targetDevice, 00804 psizel); 00805 00806 IViewObject2_Release(cacheView); 00807 00808 return hres; 00809 } 00810 00811 /************************************************************************ 00812 * DefaultHandler_Advise (IOleObject) 00813 * 00814 * The default handler's implementation of this method simply 00815 * delegates to the OleAdviseHolder. 00816 * 00817 * See Windows documentation for more details on IOleObject methods. 00818 */ 00819 static HRESULT WINAPI DefaultHandler_Advise( 00820 IOleObject* iface, 00821 IAdviseSink* pAdvSink, 00822 DWORD* pdwConnection) 00823 { 00824 HRESULT hres = S_OK; 00825 DefaultHandler *This = impl_from_IOleObject(iface); 00826 00827 TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection); 00828 00829 /* Make sure we have an advise holder before we start. */ 00830 if (!This->oleAdviseHolder) 00831 hres = CreateOleAdviseHolder(&This->oleAdviseHolder); 00832 00833 if (SUCCEEDED(hres)) 00834 hres = IOleAdviseHolder_Advise(This->oleAdviseHolder, 00835 pAdvSink, 00836 pdwConnection); 00837 00838 return hres; 00839 } 00840 00841 /************************************************************************ 00842 * DefaultHandler_Unadvise (IOleObject) 00843 * 00844 * The default handler's implementation of this method simply 00845 * delegates to the OleAdviseHolder. 00846 * 00847 * See Windows documentation for more details on IOleObject methods. 00848 */ 00849 static HRESULT WINAPI DefaultHandler_Unadvise( 00850 IOleObject* iface, 00851 DWORD dwConnection) 00852 { 00853 DefaultHandler *This = impl_from_IOleObject(iface); 00854 00855 TRACE("(%p, %d)\n", iface, dwConnection); 00856 00857 /* 00858 * If we don't have an advise holder yet, it means we don't have 00859 * a connection. 00860 */ 00861 if (!This->oleAdviseHolder) 00862 return OLE_E_NOCONNECTION; 00863 00864 return IOleAdviseHolder_Unadvise(This->oleAdviseHolder, 00865 dwConnection); 00866 } 00867 00868 /************************************************************************ 00869 * DefaultHandler_EnumAdvise (IOleObject) 00870 * 00871 * The default handler's implementation of this method simply 00872 * delegates to the OleAdviseHolder. 00873 * 00874 * See Windows documentation for more details on IOleObject methods. 00875 */ 00876 static HRESULT WINAPI DefaultHandler_EnumAdvise( 00877 IOleObject* iface, 00878 IEnumSTATDATA** ppenumAdvise) 00879 { 00880 DefaultHandler *This = impl_from_IOleObject(iface); 00881 00882 TRACE("(%p, %p)\n", iface, ppenumAdvise); 00883 00884 if (!ppenumAdvise) 00885 return E_POINTER; 00886 00887 *ppenumAdvise = NULL; 00888 00889 if (!This->oleAdviseHolder) 00890 return S_OK; 00891 00892 return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder, ppenumAdvise); 00893 } 00894 00895 /************************************************************************ 00896 * DefaultHandler_GetMiscStatus (IOleObject) 00897 * 00898 * The default handler's implementation of this method simply delegates 00899 * to OleRegGetMiscStatus. 00900 * 00901 * See Windows documentation for more details on IOleObject methods. 00902 */ 00903 static HRESULT WINAPI DefaultHandler_GetMiscStatus( 00904 IOleObject* iface, 00905 DWORD dwAspect, 00906 DWORD* pdwStatus) 00907 { 00908 HRESULT hres; 00909 DefaultHandler *This = impl_from_IOleObject(iface); 00910 00911 TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus); 00912 00913 if (object_is_running(This)) 00914 return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus); 00915 00916 hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus); 00917 00918 if (FAILED(hres)) 00919 *pdwStatus = 0; 00920 00921 return hres; 00922 } 00923 00924 /************************************************************************ 00925 * DefaultHandler_SetColorScheme (IOleObject) 00926 * 00927 * This method is meaningless if the server is not running 00928 * 00929 * See Windows documentation for more details on IOleObject methods. 00930 */ 00931 static HRESULT WINAPI DefaultHandler_SetColorScheme( 00932 IOleObject* iface, 00933 struct tagLOGPALETTE* pLogpal) 00934 { 00935 DefaultHandler *This = impl_from_IOleObject(iface); 00936 00937 TRACE("(%p, %p))\n", iface, pLogpal); 00938 00939 if (object_is_running(This)) 00940 return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal); 00941 00942 return OLE_E_NOTRUNNING; 00943 } 00944 00945 /********************************************************* 00946 * Methods implementation for the IDataObject part of 00947 * the DefaultHandler class. 00948 */ 00949 00950 /************************************************************************ 00951 * DefaultHandler_IDataObject_QueryInterface (IUnknown) 00952 * 00953 * See Windows documentation for more details on IUnknown methods. 00954 */ 00955 static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface( 00956 IDataObject* iface, 00957 REFIID riid, 00958 void** ppvObject) 00959 { 00960 DefaultHandler *This = impl_from_IDataObject(iface); 00961 00962 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject); 00963 } 00964 00965 /************************************************************************ 00966 * DefaultHandler_IDataObject_AddRef (IUnknown) 00967 * 00968 * See Windows documentation for more details on IUnknown methods. 00969 */ 00970 static ULONG WINAPI DefaultHandler_IDataObject_AddRef( 00971 IDataObject* iface) 00972 { 00973 DefaultHandler *This = impl_from_IDataObject(iface); 00974 00975 return IUnknown_AddRef(This->outerUnknown); 00976 } 00977 00978 /************************************************************************ 00979 * DefaultHandler_IDataObject_Release (IUnknown) 00980 * 00981 * See Windows documentation for more details on IUnknown methods. 00982 */ 00983 static ULONG WINAPI DefaultHandler_IDataObject_Release( 00984 IDataObject* iface) 00985 { 00986 DefaultHandler *This = impl_from_IDataObject(iface); 00987 00988 return IUnknown_Release(This->outerUnknown); 00989 } 00990 00991 /************************************************************************ 00992 * DefaultHandler_GetData 00993 * 00994 * Get Data from a source dataobject using format pformatetcIn->cfFormat 00995 * See Windows documentation for more details on GetData. 00996 * Default handler's implementation of this method delegates to the cache. 00997 */ 00998 static HRESULT WINAPI DefaultHandler_GetData( 00999 IDataObject* iface, 01000 LPFORMATETC pformatetcIn, 01001 STGMEDIUM* pmedium) 01002 { 01003 IDataObject* cacheDataObject = NULL; 01004 HRESULT hres; 01005 01006 DefaultHandler *This = impl_from_IDataObject(iface); 01007 01008 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium); 01009 01010 hres = IUnknown_QueryInterface(This->dataCache, 01011 &IID_IDataObject, 01012 (void**)&cacheDataObject); 01013 01014 if (FAILED(hres)) 01015 return E_UNEXPECTED; 01016 01017 hres = IDataObject_GetData(cacheDataObject, 01018 pformatetcIn, 01019 pmedium); 01020 01021 IDataObject_Release(cacheDataObject); 01022 01023 if (FAILED(hres) && This->pDataDelegate) 01024 hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium); 01025 01026 return hres; 01027 } 01028 01029 static HRESULT WINAPI DefaultHandler_GetDataHere( 01030 IDataObject* iface, 01031 LPFORMATETC pformatetc, 01032 STGMEDIUM* pmedium) 01033 { 01034 FIXME(": Stub\n"); 01035 return E_NOTIMPL; 01036 } 01037 01038 /************************************************************************ 01039 * DefaultHandler_QueryGetData (IDataObject) 01040 * 01041 * The default handler's implementation of this method delegates to 01042 * the cache. 01043 * 01044 * See Windows documentation for more details on IDataObject methods. 01045 */ 01046 static HRESULT WINAPI DefaultHandler_QueryGetData( 01047 IDataObject* iface, 01048 LPFORMATETC pformatetc) 01049 { 01050 IDataObject* cacheDataObject = NULL; 01051 HRESULT hres; 01052 01053 DefaultHandler *This = impl_from_IDataObject(iface); 01054 01055 TRACE("(%p, %p)\n", iface, pformatetc); 01056 01057 hres = IUnknown_QueryInterface(This->dataCache, 01058 &IID_IDataObject, 01059 (void**)&cacheDataObject); 01060 01061 if (FAILED(hres)) 01062 return E_UNEXPECTED; 01063 01064 hres = IDataObject_QueryGetData(cacheDataObject, 01065 pformatetc); 01066 01067 IDataObject_Release(cacheDataObject); 01068 01069 if (FAILED(hres) && This->pDataDelegate) 01070 hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc); 01071 01072 return hres; 01073 } 01074 01075 /************************************************************************ 01076 * DefaultHandler_GetCanonicalFormatEtc (IDataObject) 01077 * 01078 * This method is meaningless if the server is not running 01079 * 01080 * See Windows documentation for more details on IDataObject methods. 01081 */ 01082 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc( 01083 IDataObject* iface, 01084 LPFORMATETC pformatetcIn, 01085 LPFORMATETC pformatetcOut) 01086 { 01087 DefaultHandler *This = impl_from_IDataObject(iface); 01088 01089 TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut); 01090 01091 if (!This->pDataDelegate) 01092 return OLE_E_NOTRUNNING; 01093 01094 return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut); 01095 } 01096 01097 /************************************************************************ 01098 * DefaultHandler_SetData (IDataObject) 01099 * 01100 * The default handler's implementation of this method delegates to 01101 * the cache. 01102 * 01103 * See Windows documentation for more details on IDataObject methods. 01104 */ 01105 static HRESULT WINAPI DefaultHandler_SetData( 01106 IDataObject* iface, 01107 LPFORMATETC pformatetc, 01108 STGMEDIUM* pmedium, 01109 BOOL fRelease) 01110 { 01111 DefaultHandler *This = impl_from_IDataObject(iface); 01112 IDataObject* cacheDataObject = NULL; 01113 HRESULT hres; 01114 01115 TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease); 01116 01117 hres = IUnknown_QueryInterface(This->dataCache, 01118 &IID_IDataObject, 01119 (void**)&cacheDataObject); 01120 01121 if (FAILED(hres)) 01122 return E_UNEXPECTED; 01123 01124 hres = IDataObject_SetData(cacheDataObject, 01125 pformatetc, 01126 pmedium, 01127 fRelease); 01128 01129 IDataObject_Release(cacheDataObject); 01130 01131 return hres; 01132 } 01133 01134 /************************************************************************ 01135 * DefaultHandler_EnumFormatEtc (IDataObject) 01136 * 01137 * The default handler's implementation of This method simply delegates 01138 * to OleRegEnumFormatEtc. 01139 * 01140 * See Windows documentation for more details on IDataObject methods. 01141 */ 01142 static HRESULT WINAPI DefaultHandler_EnumFormatEtc( 01143 IDataObject* iface, 01144 DWORD dwDirection, 01145 IEnumFORMATETC** ppenumFormatEtc) 01146 { 01147 DefaultHandler *This = impl_from_IDataObject(iface); 01148 01149 TRACE("(%p, %x, %p)\n", iface, dwDirection, ppenumFormatEtc); 01150 01151 return OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc); 01152 } 01153 01154 /************************************************************************ 01155 * DefaultHandler_DAdvise (IDataObject) 01156 * 01157 * The default handler's implementation of this method simply 01158 * delegates to the DataAdviseHolder. 01159 * 01160 * See Windows documentation for more details on IDataObject methods. 01161 */ 01162 static HRESULT WINAPI DefaultHandler_DAdvise( 01163 IDataObject* iface, 01164 FORMATETC* pformatetc, 01165 DWORD advf, 01166 IAdviseSink* pAdvSink, 01167 DWORD* pdwConnection) 01168 { 01169 HRESULT hres = S_OK; 01170 DefaultHandler *This = impl_from_IDataObject(iface); 01171 01172 TRACE("(%p, %p, %d, %p, %p)\n", 01173 iface, pformatetc, advf, pAdvSink, pdwConnection); 01174 01175 /* Make sure we have a data advise holder before we start. */ 01176 if (!This->dataAdviseHolder) 01177 { 01178 hres = CreateDataAdviseHolder(&This->dataAdviseHolder); 01179 if (SUCCEEDED(hres) && This->pDataDelegate) 01180 DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate); 01181 } 01182 01183 if (SUCCEEDED(hres)) 01184 hres = IDataAdviseHolder_Advise(This->dataAdviseHolder, 01185 iface, 01186 pformatetc, 01187 advf, 01188 pAdvSink, 01189 pdwConnection); 01190 01191 return hres; 01192 } 01193 01194 /************************************************************************ 01195 * DefaultHandler_DUnadvise (IDataObject) 01196 * 01197 * The default handler's implementation of this method simply 01198 * delegates to the DataAdviseHolder. 01199 * 01200 * See Windows documentation for more details on IDataObject methods. 01201 */ 01202 static HRESULT WINAPI DefaultHandler_DUnadvise( 01203 IDataObject* iface, 01204 DWORD dwConnection) 01205 { 01206 DefaultHandler *This = impl_from_IDataObject(iface); 01207 01208 TRACE("(%p, %d)\n", iface, dwConnection); 01209 01210 /* 01211 * If we don't have a data advise holder yet, it means that 01212 * we don't have any connections.. 01213 */ 01214 if (!This->dataAdviseHolder) 01215 return OLE_E_NOCONNECTION; 01216 01217 return IDataAdviseHolder_Unadvise(This->dataAdviseHolder, 01218 dwConnection); 01219 } 01220 01221 /************************************************************************ 01222 * DefaultHandler_EnumDAdvise (IDataObject) 01223 * 01224 * The default handler's implementation of this method simply 01225 * delegates to the DataAdviseHolder. 01226 * 01227 * See Windows documentation for more details on IDataObject methods. 01228 */ 01229 static HRESULT WINAPI DefaultHandler_EnumDAdvise( 01230 IDataObject* iface, 01231 IEnumSTATDATA** ppenumAdvise) 01232 { 01233 DefaultHandler *This = impl_from_IDataObject(iface); 01234 01235 TRACE("(%p, %p)\n", iface, ppenumAdvise); 01236 01237 if (!ppenumAdvise) 01238 return E_POINTER; 01239 01240 *ppenumAdvise = NULL; 01241 01242 /* If we have a data advise holder object, delegate. */ 01243 if (This->dataAdviseHolder) 01244 return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder, 01245 ppenumAdvise); 01246 01247 return S_OK; 01248 } 01249 01250 /********************************************************* 01251 * Methods implementation for the IRunnableObject part 01252 * of the DefaultHandler class. 01253 */ 01254 01255 /************************************************************************ 01256 * DefaultHandler_IRunnableObject_QueryInterface (IUnknown) 01257 * 01258 * See Windows documentation for more details on IUnknown methods. 01259 */ 01260 static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface( 01261 IRunnableObject* iface, 01262 REFIID riid, 01263 void** ppvObject) 01264 { 01265 DefaultHandler *This = impl_from_IRunnableObject(iface); 01266 01267 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject); 01268 } 01269 01270 /************************************************************************ 01271 * DefaultHandler_IRunnableObject_AddRef (IUnknown) 01272 * 01273 * See Windows documentation for more details on IUnknown methods. 01274 */ 01275 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef( 01276 IRunnableObject* iface) 01277 { 01278 DefaultHandler *This = impl_from_IRunnableObject(iface); 01279 01280 return IUnknown_AddRef(This->outerUnknown); 01281 } 01282 01283 /************************************************************************ 01284 * DefaultHandler_IRunnableObject_Release (IUnknown) 01285 * 01286 * See Windows documentation for more details on IUnknown methods. 01287 */ 01288 static ULONG WINAPI DefaultHandler_IRunnableObject_Release( 01289 IRunnableObject* iface) 01290 { 01291 DefaultHandler *This = impl_from_IRunnableObject(iface); 01292 01293 return IUnknown_Release(This->outerUnknown); 01294 } 01295 01296 /************************************************************************ 01297 * DefaultHandler_GetRunningClass (IRunnableObject) 01298 * 01299 * See Windows documentation for more details on IRunnableObject methods. 01300 */ 01301 static HRESULT WINAPI DefaultHandler_GetRunningClass( 01302 IRunnableObject* iface, 01303 LPCLSID lpClsid) 01304 { 01305 FIXME("()\n"); 01306 return S_OK; 01307 } 01308 01309 static HRESULT WINAPI DefaultHandler_Run( 01310 IRunnableObject* iface, 01311 IBindCtx* pbc) 01312 { 01313 DefaultHandler *This = impl_from_IRunnableObject(iface); 01314 HRESULT hr; 01315 01316 FIXME("(%p): semi-stub\n", pbc); 01317 01318 /* already running? if so nothing to do */ 01319 if (object_is_running(This)) 01320 return S_OK; 01321 01322 release_delegates(This); 01323 01324 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER, 01325 &IID_IOleObject, (void **)&This->pOleDelegate); 01326 if (FAILED(hr)) 01327 return hr; 01328 01329 This->object_state = object_state_running; 01330 01331 hr = IOleObject_Advise(This->pOleDelegate, &This->IAdviseSink_iface, &This->dwAdvConn); 01332 01333 if (SUCCEEDED(hr) && This->clientSite) 01334 hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite); 01335 01336 if (SUCCEEDED(hr)) 01337 { 01338 IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, 01339 (void **)&This->pPSDelegate); 01340 if (This->pPSDelegate) 01341 { 01342 if(This->storage_state == storage_state_initialised) 01343 hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage); 01344 else if(This->storage_state == storage_state_loaded) 01345 hr = IPersistStorage_Load(This->pPSDelegate, This->storage); 01346 } 01347 } 01348 01349 if (SUCCEEDED(hr) && This->containerApp) 01350 hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp, 01351 This->containerObj); 01352 01353 /* FIXME: do more stuff here: 01354 * - IOleObject_GetMiscStatus 01355 * - IOleObject_GetMoniker 01356 * - IOleCache_OnRun 01357 */ 01358 01359 if (SUCCEEDED(hr)) 01360 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, 01361 (void **)&This->pDataDelegate); 01362 01363 if (SUCCEEDED(hr) && This->dataAdviseHolder) 01364 hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate); 01365 01366 if (FAILED(hr)) 01367 { 01368 DefaultHandler_Stop(This); 01369 release_delegates(This); 01370 } 01371 01372 return hr; 01373 } 01374 01375 /************************************************************************ 01376 * DefaultHandler_IsRunning (IRunnableObject) 01377 * 01378 * See Windows documentation for more details on IRunnableObject methods. 01379 */ 01380 static BOOL WINAPI DefaultHandler_IsRunning( 01381 IRunnableObject* iface) 01382 { 01383 DefaultHandler *This = impl_from_IRunnableObject(iface); 01384 01385 TRACE("()\n"); 01386 01387 if (This->object_state == object_state_running) 01388 return TRUE; 01389 else 01390 return FALSE; 01391 } 01392 01393 /************************************************************************ 01394 * DefaultHandler_LockRunning (IRunnableObject) 01395 * 01396 * See Windows documentation for more details on IRunnableObject methods. 01397 */ 01398 static HRESULT WINAPI DefaultHandler_LockRunning( 01399 IRunnableObject* iface, 01400 BOOL fLock, 01401 BOOL fLastUnlockCloses) 01402 { 01403 FIXME("()\n"); 01404 return S_OK; 01405 } 01406 01407 /************************************************************************ 01408 * DefaultHandler_SetContainedObject (IRunnableObject) 01409 * 01410 * See Windows documentation for more details on IRunnableObject methods. 01411 */ 01412 static HRESULT WINAPI DefaultHandler_SetContainedObject( 01413 IRunnableObject* iface, 01414 BOOL fContained) 01415 { 01416 FIXME("()\n"); 01417 return S_OK; 01418 } 01419 01420 static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface( 01421 IAdviseSink *iface, 01422 REFIID riid, 01423 void **ppvObject) 01424 { 01425 if (IsEqualIID(riid, &IID_IUnknown) || 01426 IsEqualIID(riid, &IID_IAdviseSink)) 01427 { 01428 *ppvObject = iface; 01429 IAdviseSink_AddRef(iface); 01430 return S_OK; 01431 } 01432 01433 return E_NOINTERFACE; 01434 } 01435 01436 static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef( 01437 IAdviseSink *iface) 01438 { 01439 DefaultHandler *This = impl_from_IAdviseSink(iface); 01440 01441 return IUnknown_AddRef(&This->IUnknown_iface); 01442 } 01443 01444 static ULONG WINAPI DefaultHandler_IAdviseSink_Release( 01445 IAdviseSink *iface) 01446 { 01447 DefaultHandler *This = impl_from_IAdviseSink(iface); 01448 01449 return IUnknown_Release(&This->IUnknown_iface); 01450 } 01451 01452 static void WINAPI DefaultHandler_IAdviseSink_OnDataChange( 01453 IAdviseSink *iface, 01454 FORMATETC *pFormatetc, 01455 STGMEDIUM *pStgmed) 01456 { 01457 FIXME(": stub\n"); 01458 } 01459 01460 static void WINAPI DefaultHandler_IAdviseSink_OnViewChange( 01461 IAdviseSink *iface, 01462 DWORD dwAspect, 01463 LONG lindex) 01464 { 01465 FIXME(": stub\n"); 01466 } 01467 01468 static void WINAPI DefaultHandler_IAdviseSink_OnRename( 01469 IAdviseSink *iface, 01470 IMoniker *pmk) 01471 { 01472 DefaultHandler *This = impl_from_IAdviseSink(iface); 01473 01474 TRACE("(%p)\n", pmk); 01475 01476 if (This->oleAdviseHolder) 01477 IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk); 01478 } 01479 01480 static void WINAPI DefaultHandler_IAdviseSink_OnSave( 01481 IAdviseSink *iface) 01482 { 01483 DefaultHandler *This = impl_from_IAdviseSink(iface); 01484 01485 TRACE("()\n"); 01486 01487 if (This->oleAdviseHolder) 01488 IOleAdviseHolder_SendOnSave(This->oleAdviseHolder); 01489 } 01490 01491 static void WINAPI DefaultHandler_IAdviseSink_OnClose( 01492 IAdviseSink *iface) 01493 { 01494 DefaultHandler *This = impl_from_IAdviseSink(iface); 01495 01496 TRACE("()\n"); 01497 01498 if (This->oleAdviseHolder) 01499 IOleAdviseHolder_SendOnClose(This->oleAdviseHolder); 01500 01501 DefaultHandler_Stop(This); 01502 } 01503 01504 01505 /************************************************************************ 01506 * DefaultHandler_IPersistStorage_QueryInterface 01507 * 01508 */ 01509 static HRESULT WINAPI DefaultHandler_IPersistStorage_QueryInterface( 01510 IPersistStorage* iface, 01511 REFIID riid, 01512 void** ppvObject) 01513 { 01514 DefaultHandler *This = impl_from_IPersistStorage(iface); 01515 01516 return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject); 01517 } 01518 01519 /************************************************************************ 01520 * DefaultHandler_IPersistStorage_AddRef 01521 * 01522 */ 01523 static ULONG WINAPI DefaultHandler_IPersistStorage_AddRef( 01524 IPersistStorage* iface) 01525 { 01526 DefaultHandler *This = impl_from_IPersistStorage(iface); 01527 01528 return IUnknown_AddRef(This->outerUnknown); 01529 } 01530 01531 /************************************************************************ 01532 * DefaultHandler_IPersistStorage_Release 01533 * 01534 */ 01535 static ULONG WINAPI DefaultHandler_IPersistStorage_Release( 01536 IPersistStorage* iface) 01537 { 01538 DefaultHandler *This = impl_from_IPersistStorage(iface); 01539 01540 return IUnknown_Release(This->outerUnknown); 01541 } 01542 01543 /************************************************************************ 01544 * DefaultHandler_IPersistStorage_GetClassID 01545 * 01546 */ 01547 static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID( 01548 IPersistStorage* iface, 01549 CLSID* clsid) 01550 { 01551 DefaultHandler *This = impl_from_IPersistStorage(iface); 01552 HRESULT hr; 01553 01554 TRACE("(%p)->(%p)\n", iface, clsid); 01555 01556 if(object_is_running(This)) 01557 hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid); 01558 else 01559 hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid); 01560 01561 return hr; 01562 } 01563 01564 /************************************************************************ 01565 * DefaultHandler_IPersistStorage_IsDirty 01566 * 01567 */ 01568 static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty( 01569 IPersistStorage* iface) 01570 { 01571 DefaultHandler *This = impl_from_IPersistStorage(iface); 01572 HRESULT hr; 01573 01574 TRACE("(%p)\n", iface); 01575 01576 hr = IPersistStorage_IsDirty(This->dataCache_PersistStg); 01577 if(hr != S_FALSE) return hr; 01578 01579 if(object_is_running(This)) 01580 hr = IPersistStorage_IsDirty(This->pPSDelegate); 01581 01582 return hr; 01583 } 01584 01585 /*********************************************************************** 01586 * init_ole_stream 01587 * 01588 * Creates the '\1Ole' stream. 01589 * The format of this stream is as follows: 01590 * 01591 * DWORD Version == 0x02000001 01592 * DWORD Flags - low bit set indicates the object is a link otherwise it's embedded. 01593 * DWORD LinkupdateOption - [MS-OLEDS describes this as an implementation specific hint 01594 * supplied by the app that creates the data structure. May be 01595 * ignored on processing]. 01596 * 01597 * DWORD Reserved == 0 01598 * DWORD MonikerStreamSize - size of the rest of the data (ie CLSID + moniker stream data). 01599 * CLSID clsid - class id of object capable of processing the moniker 01600 * BYTE data[] - moniker data for a link 01601 */ 01602 01603 static const WCHAR OleStream[] = {1,'O','l','e',0}; 01604 typedef struct 01605 { 01606 DWORD version; 01607 DWORD flags; 01608 DWORD link_update_opt; 01609 DWORD res; 01610 DWORD moniker_size; 01611 } ole_stream_header_t; 01612 static const DWORD ole_stream_version = 0x02000001; 01613 01614 static void init_ole_stream(IStorage *storage) 01615 { 01616 HRESULT hr; 01617 IStream *stream; 01618 01619 hr = IStorage_CreateStream(storage, OleStream, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &stream); 01620 if(SUCCEEDED(hr)) 01621 { 01622 DWORD written; 01623 ole_stream_header_t header; 01624 01625 header.version = ole_stream_version; 01626 header.flags = 0; 01627 header.link_update_opt = 0; 01628 header.res = 0; 01629 header.moniker_size = 0; 01630 01631 IStream_Write(stream, &header, sizeof(header), &written); 01632 IStream_Release(stream); 01633 } 01634 return; 01635 } 01636 01637 static HRESULT load_ole_stream(DefaultHandler *This, IStorage *storage) 01638 { 01639 IStream *stream; 01640 HRESULT hr; 01641 01642 hr = IStorage_OpenStream(storage, OleStream, NULL, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &stream); 01643 01644 if(SUCCEEDED(hr)) 01645 { 01646 DWORD read; 01647 ole_stream_header_t header; 01648 01649 hr = IStream_Read(stream, &header, sizeof(header), &read); 01650 if(hr == S_OK && read == sizeof(header) && header.version == ole_stream_version) 01651 { 01652 if(header.flags & 1) 01653 { 01654 /* FIXME: Read the moniker and deal with the link */ 01655 FIXME("Linked objects are not supported yet\n"); 01656 } 01657 } 01658 else 01659 { 01660 WARN("Incorrect OleStream header\n"); 01661 hr = DV_E_CLIPFORMAT; 01662 } 01663 IStream_Release(stream); 01664 } 01665 else 01666 { 01667 init_ole_stream(storage); 01668 hr = S_OK; 01669 } 01670 return hr; 01671 } 01672 01673 /************************************************************************ 01674 * DefaultHandler_IPersistStorage_InitNew 01675 * 01676 */ 01677 static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew( 01678 IPersistStorage* iface, 01679 IStorage* pStg) 01680 { 01681 DefaultHandler *This = impl_from_IPersistStorage(iface); 01682 HRESULT hr; 01683 01684 TRACE("(%p)->(%p)\n", iface, pStg); 01685 init_ole_stream(pStg); 01686 01687 hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg); 01688 01689 if(SUCCEEDED(hr) && object_is_running(This)) 01690 hr = IPersistStorage_InitNew(This->pPSDelegate, pStg); 01691 01692 if(SUCCEEDED(hr)) 01693 { 01694 IStorage_AddRef(pStg); 01695 This->storage = pStg; 01696 This->storage_state = storage_state_initialised; 01697 } 01698 01699 return hr; 01700 } 01701 01702 01703 /************************************************************************ 01704 * DefaultHandler_IPersistStorage_Load 01705 * 01706 */ 01707 static HRESULT WINAPI DefaultHandler_IPersistStorage_Load( 01708 IPersistStorage* iface, 01709 IStorage* pStg) 01710 { 01711 DefaultHandler *This = impl_from_IPersistStorage(iface); 01712 HRESULT hr; 01713 01714 TRACE("(%p)->(%p)\n", iface, pStg); 01715 01716 hr = load_ole_stream(This, pStg); 01717 01718 if(SUCCEEDED(hr)) 01719 hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg); 01720 01721 if(SUCCEEDED(hr) && object_is_running(This)) 01722 hr = IPersistStorage_Load(This->pPSDelegate, pStg); 01723 01724 if(SUCCEEDED(hr)) 01725 { 01726 IStorage_AddRef(pStg); 01727 This->storage = pStg; 01728 This->storage_state = storage_state_loaded; 01729 } 01730 return hr; 01731 } 01732 01733 01734 /************************************************************************ 01735 * DefaultHandler_IPersistStorage_Save 01736 * 01737 */ 01738 static HRESULT WINAPI DefaultHandler_IPersistStorage_Save( 01739 IPersistStorage* iface, 01740 IStorage* pStgSave, 01741 BOOL fSameAsLoad) 01742 { 01743 DefaultHandler *This = impl_from_IPersistStorage(iface); 01744 HRESULT hr; 01745 01746 TRACE("(%p)->(%p, %d)\n", iface, pStgSave, fSameAsLoad); 01747 01748 hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad); 01749 if(SUCCEEDED(hr) && object_is_running(This)) 01750 hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad); 01751 01752 return hr; 01753 } 01754 01755 01756 /************************************************************************ 01757 * DefaultHandler_IPersistStorage_SaveCompleted 01758 * 01759 */ 01760 static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted( 01761 IPersistStorage* iface, 01762 IStorage* pStgNew) 01763 { 01764 DefaultHandler *This = impl_from_IPersistStorage(iface); 01765 HRESULT hr; 01766 01767 TRACE("(%p)->(%p)\n", iface, pStgNew); 01768 01769 hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew); 01770 01771 if(SUCCEEDED(hr) && object_is_running(This)) 01772 hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew); 01773 01774 if(pStgNew) 01775 { 01776 IStorage_AddRef(pStgNew); 01777 if(This->storage) IStorage_Release(This->storage); 01778 This->storage = pStgNew; 01779 This->storage_state = storage_state_loaded; 01780 } 01781 01782 return hr; 01783 } 01784 01785 01786 /************************************************************************ 01787 * DefaultHandler_IPersistStorage_HandsOffStorage 01788 * 01789 */ 01790 static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage( 01791 IPersistStorage* iface) 01792 { 01793 DefaultHandler *This = impl_from_IPersistStorage(iface); 01794 HRESULT hr; 01795 01796 TRACE("(%p)\n", iface); 01797 01798 hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg); 01799 01800 if(SUCCEEDED(hr) && object_is_running(This)) 01801 hr = IPersistStorage_HandsOffStorage(This->pPSDelegate); 01802 01803 if(This->storage) IStorage_Release(This->storage); 01804 This->storage = NULL; 01805 This->storage_state = storage_state_uninitialised; 01806 01807 return hr; 01808 } 01809 01810 01811 /* 01812 * Virtual function tables for the DefaultHandler class. 01813 */ 01814 static const IOleObjectVtbl DefaultHandler_IOleObject_VTable = 01815 { 01816 DefaultHandler_QueryInterface, 01817 DefaultHandler_AddRef, 01818 DefaultHandler_Release, 01819 DefaultHandler_SetClientSite, 01820 DefaultHandler_GetClientSite, 01821 DefaultHandler_SetHostNames, 01822 DefaultHandler_Close, 01823 DefaultHandler_SetMoniker, 01824 DefaultHandler_GetMoniker, 01825 DefaultHandler_InitFromData, 01826 DefaultHandler_GetClipboardData, 01827 DefaultHandler_DoVerb, 01828 DefaultHandler_EnumVerbs, 01829 DefaultHandler_Update, 01830 DefaultHandler_IsUpToDate, 01831 DefaultHandler_GetUserClassID, 01832 DefaultHandler_GetUserType, 01833 DefaultHandler_SetExtent, 01834 DefaultHandler_GetExtent, 01835 DefaultHandler_Advise, 01836 DefaultHandler_Unadvise, 01837 DefaultHandler_EnumAdvise, 01838 DefaultHandler_GetMiscStatus, 01839 DefaultHandler_SetColorScheme 01840 }; 01841 01842 static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable = 01843 { 01844 DefaultHandler_NDIUnknown_QueryInterface, 01845 DefaultHandler_NDIUnknown_AddRef, 01846 DefaultHandler_NDIUnknown_Release, 01847 }; 01848 01849 static const IDataObjectVtbl DefaultHandler_IDataObject_VTable = 01850 { 01851 DefaultHandler_IDataObject_QueryInterface, 01852 DefaultHandler_IDataObject_AddRef, 01853 DefaultHandler_IDataObject_Release, 01854 DefaultHandler_GetData, 01855 DefaultHandler_GetDataHere, 01856 DefaultHandler_QueryGetData, 01857 DefaultHandler_GetCanonicalFormatEtc, 01858 DefaultHandler_SetData, 01859 DefaultHandler_EnumFormatEtc, 01860 DefaultHandler_DAdvise, 01861 DefaultHandler_DUnadvise, 01862 DefaultHandler_EnumDAdvise 01863 }; 01864 01865 static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable = 01866 { 01867 DefaultHandler_IRunnableObject_QueryInterface, 01868 DefaultHandler_IRunnableObject_AddRef, 01869 DefaultHandler_IRunnableObject_Release, 01870 DefaultHandler_GetRunningClass, 01871 DefaultHandler_Run, 01872 DefaultHandler_IsRunning, 01873 DefaultHandler_LockRunning, 01874 DefaultHandler_SetContainedObject 01875 }; 01876 01877 static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable = 01878 { 01879 DefaultHandler_IAdviseSink_QueryInterface, 01880 DefaultHandler_IAdviseSink_AddRef, 01881 DefaultHandler_IAdviseSink_Release, 01882 DefaultHandler_IAdviseSink_OnDataChange, 01883 DefaultHandler_IAdviseSink_OnViewChange, 01884 DefaultHandler_IAdviseSink_OnRename, 01885 DefaultHandler_IAdviseSink_OnSave, 01886 DefaultHandler_IAdviseSink_OnClose 01887 }; 01888 01889 static const IPersistStorageVtbl DefaultHandler_IPersistStorage_VTable = 01890 { 01891 DefaultHandler_IPersistStorage_QueryInterface, 01892 DefaultHandler_IPersistStorage_AddRef, 01893 DefaultHandler_IPersistStorage_Release, 01894 DefaultHandler_IPersistStorage_GetClassID, 01895 DefaultHandler_IPersistStorage_IsDirty, 01896 DefaultHandler_IPersistStorage_InitNew, 01897 DefaultHandler_IPersistStorage_Load, 01898 DefaultHandler_IPersistStorage_Save, 01899 DefaultHandler_IPersistStorage_SaveCompleted, 01900 DefaultHandler_IPersistStorage_HandsOffStorage 01901 }; 01902 01903 /********************************************************* 01904 * Methods implementation for the DefaultHandler class. 01905 */ 01906 static DefaultHandler* DefaultHandler_Construct( 01907 REFCLSID clsid, 01908 LPUNKNOWN pUnkOuter, 01909 DWORD flags, 01910 IClassFactory *pCF) 01911 { 01912 DefaultHandler* This = NULL; 01913 HRESULT hr; 01914 01915 This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler)); 01916 01917 if (!This) 01918 return This; 01919 01920 This->IOleObject_iface.lpVtbl = &DefaultHandler_IOleObject_VTable; 01921 This->IUnknown_iface.lpVtbl = &DefaultHandler_NDIUnknown_VTable; 01922 This->IDataObject_iface.lpVtbl = &DefaultHandler_IDataObject_VTable; 01923 This->IRunnableObject_iface.lpVtbl = &DefaultHandler_IRunnableObject_VTable; 01924 This->IAdviseSink_iface.lpVtbl = &DefaultHandler_IAdviseSink_VTable; 01925 This->IPersistStorage_iface.lpVtbl = &DefaultHandler_IPersistStorage_VTable; 01926 01927 This->inproc_server = (flags & EMBDHLP_INPROC_SERVER) ? TRUE : FALSE; 01928 01929 /* 01930 * Start with one reference count. The caller of this function 01931 * must release the interface pointer when it is done. 01932 */ 01933 This->ref = 1; 01934 01935 /* 01936 * Initialize the outer unknown 01937 * We don't keep a reference on the outer unknown since, the way 01938 * aggregation works, our lifetime is at least as large as its 01939 * lifetime. 01940 */ 01941 if (!pUnkOuter) 01942 pUnkOuter = &This->IUnknown_iface; 01943 01944 This->outerUnknown = pUnkOuter; 01945 01946 /* 01947 * Create a datacache object. 01948 * We aggregate with the datacache. Make sure we pass our outer 01949 * unknown as the datacache's outer unknown. 01950 */ 01951 hr = CreateDataCache(This->outerUnknown, 01952 clsid, 01953 &IID_IUnknown, 01954 (void**)&This->dataCache); 01955 if(SUCCEEDED(hr)) 01956 { 01957 hr = IUnknown_QueryInterface(This->dataCache, &IID_IPersistStorage, (void**)&This->dataCache_PersistStg); 01958 /* keeping a reference to This->dataCache_PersistStg causes us to keep a 01959 * reference on the outer object */ 01960 if (SUCCEEDED(hr)) 01961 IUnknown_Release(This->outerUnknown); 01962 else 01963 IUnknown_Release(This->dataCache); 01964 } 01965 if(FAILED(hr)) 01966 { 01967 ERR("Unexpected error creating data cache\n"); 01968 HeapFree(GetProcessHeap(), 0, This); 01969 return NULL; 01970 } 01971 01972 This->clsid = *clsid; 01973 This->clientSite = NULL; 01974 This->oleAdviseHolder = NULL; 01975 This->dataAdviseHolder = NULL; 01976 This->containerApp = NULL; 01977 This->containerObj = NULL; 01978 This->pOleDelegate = NULL; 01979 This->pPSDelegate = NULL; 01980 This->pDataDelegate = NULL; 01981 This->object_state = object_state_not_running; 01982 01983 This->dwAdvConn = 0; 01984 This->storage = NULL; 01985 This->storage_state = storage_state_uninitialised; 01986 01987 if (This->inproc_server && !(flags & EMBDHLP_DELAYCREATE)) 01988 { 01989 HRESULT hr; 01990 This->pCFObject = NULL; 01991 if (pCF) 01992 hr = IClassFactory_CreateInstance(pCF, NULL, &IID_IOleObject, (void **)&This->pOleDelegate); 01993 else 01994 hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_INPROC_SERVER, 01995 &IID_IOleObject, (void **)&This->pOleDelegate); 01996 if (SUCCEEDED(hr)) 01997 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate); 01998 if (SUCCEEDED(hr)) 01999 hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&This->pDataDelegate); 02000 if (SUCCEEDED(hr)) 02001 This->object_state = object_state_running; 02002 if (FAILED(hr)) 02003 WARN("object creation failed with error %08x\n", hr); 02004 } 02005 else 02006 { 02007 This->pCFObject = pCF; 02008 if (pCF) IClassFactory_AddRef(pCF); 02009 } 02010 02011 return This; 02012 } 02013 02014 static void DefaultHandler_Destroy( 02015 DefaultHandler* This) 02016 { 02017 TRACE("(%p)\n", This); 02018 02019 /* AddRef/Release may be called on this object during destruction. 02020 * Prevent the object being destroyed recursively by artificially raising 02021 * the reference count. */ 02022 This->ref = 10000; 02023 02024 /* release delegates */ 02025 DefaultHandler_Stop(This); 02026 release_delegates(This); 02027 02028 HeapFree( GetProcessHeap(), 0, This->containerApp ); 02029 This->containerApp = NULL; 02030 HeapFree( GetProcessHeap(), 0, This->containerObj ); 02031 This->containerObj = NULL; 02032 02033 if (This->dataCache) 02034 { 02035 /* to balance out the release of dataCache_PersistStg which will result 02036 * in a reference being released from the outer unknown */ 02037 IUnknown_AddRef(This->outerUnknown); 02038 IPersistStorage_Release(This->dataCache_PersistStg); 02039 IUnknown_Release(This->dataCache); 02040 This->dataCache_PersistStg = NULL; 02041 This->dataCache = NULL; 02042 } 02043 02044 if (This->clientSite) 02045 { 02046 IOleClientSite_Release(This->clientSite); 02047 This->clientSite = NULL; 02048 } 02049 02050 if (This->oleAdviseHolder) 02051 { 02052 IOleAdviseHolder_Release(This->oleAdviseHolder); 02053 This->oleAdviseHolder = NULL; 02054 } 02055 02056 if (This->dataAdviseHolder) 02057 { 02058 IDataAdviseHolder_Release(This->dataAdviseHolder); 02059 This->dataAdviseHolder = NULL; 02060 } 02061 02062 if (This->storage) 02063 { 02064 IStorage_Release(This->storage); 02065 This->storage = NULL; 02066 } 02067 02068 if (This->pCFObject) 02069 { 02070 IClassFactory_Release(This->pCFObject); 02071 This->pCFObject = NULL; 02072 } 02073 02074 HeapFree(GetProcessHeap(), 0, This); 02075 } 02076 02077 /****************************************************************************** 02078 * OleCreateEmbeddingHelper [OLE32.@] 02079 */ 02080 HRESULT WINAPI OleCreateEmbeddingHelper( 02081 REFCLSID clsid, 02082 LPUNKNOWN pUnkOuter, 02083 DWORD flags, 02084 IClassFactory *pCF, 02085 REFIID riid, 02086 LPVOID* ppvObj) 02087 { 02088 DefaultHandler* newHandler = NULL; 02089 HRESULT hr = S_OK; 02090 02091 TRACE("(%s, %p, %08x, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, flags, pCF, debugstr_guid(riid), ppvObj); 02092 02093 if (!ppvObj) 02094 return E_POINTER; 02095 02096 *ppvObj = NULL; 02097 02098 /* 02099 * If This handler is constructed for aggregation, make sure 02100 * the caller is requesting the IUnknown interface. 02101 * This is necessary because it's the only time the non-delegating 02102 * IUnknown pointer can be returned to the outside. 02103 */ 02104 if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid)) 02105 return CLASS_E_NOAGGREGATION; 02106 02107 /* 02108 * Try to construct a new instance of the class. 02109 */ 02110 newHandler = DefaultHandler_Construct(clsid, pUnkOuter, flags, pCF); 02111 02112 if (!newHandler) 02113 return E_OUTOFMEMORY; 02114 02115 /* 02116 * Make sure it supports the interface required by the caller. 02117 */ 02118 hr = IUnknown_QueryInterface(&newHandler->IUnknown_iface, riid, ppvObj); 02119 02120 /* 02121 * Release the reference obtained in the constructor. If 02122 * the QueryInterface was unsuccessful, it will free the class. 02123 */ 02124 IUnknown_Release(&newHandler->IUnknown_iface); 02125 02126 return hr; 02127 } 02128 02129 02130 /****************************************************************************** 02131 * OleCreateDefaultHandler [OLE32.@] 02132 */ 02133 HRESULT WINAPI OleCreateDefaultHandler(REFCLSID clsid, LPUNKNOWN pUnkOuter, 02134 REFIID riid, LPVOID* ppvObj) 02135 { 02136 TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter,debugstr_guid(riid), ppvObj); 02137 return OleCreateEmbeddingHelper(clsid, pUnkOuter, EMBDHLP_INPROC_HANDLER | EMBDHLP_CREATENOW, 02138 NULL, riid, ppvObj); 02139 } 02140 02141 typedef struct HandlerCF 02142 { 02143 IClassFactory IClassFactory_iface; 02144 LONG refs; 02145 CLSID clsid; 02146 } HandlerCF; 02147 02148 static inline HandlerCF *impl_from_IClassFactory(IClassFactory *iface) 02149 { 02150 return CONTAINING_RECORD(iface, HandlerCF, IClassFactory_iface); 02151 } 02152 02153 static HRESULT WINAPI 02154 HandlerCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid, LPVOID *ppv) 02155 { 02156 *ppv = NULL; 02157 if (IsEqualIID(riid,&IID_IUnknown) || 02158 IsEqualIID(riid,&IID_IClassFactory)) 02159 { 02160 *ppv = iface; 02161 IClassFactory_AddRef(iface); 02162 return S_OK; 02163 } 02164 return E_NOINTERFACE; 02165 } 02166 02167 static ULONG WINAPI HandlerCF_AddRef(LPCLASSFACTORY iface) 02168 { 02169 HandlerCF *This = impl_from_IClassFactory(iface); 02170 return InterlockedIncrement(&This->refs); 02171 } 02172 02173 static ULONG WINAPI HandlerCF_Release(LPCLASSFACTORY iface) 02174 { 02175 HandlerCF *This = impl_from_IClassFactory(iface); 02176 ULONG refs = InterlockedDecrement(&This->refs); 02177 if (!refs) 02178 HeapFree(GetProcessHeap(), 0, This); 02179 return refs; 02180 } 02181 02182 static HRESULT WINAPI 02183 HandlerCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pUnk, 02184 REFIID riid, LPVOID *ppv) 02185 { 02186 HandlerCF *This = impl_from_IClassFactory(iface); 02187 return OleCreateDefaultHandler(&This->clsid, pUnk, riid, ppv); 02188 } 02189 02190 static HRESULT WINAPI HandlerCF_LockServer(LPCLASSFACTORY iface, BOOL fLock) 02191 { 02192 FIXME("(%d), stub!\n",fLock); 02193 return S_OK; 02194 } 02195 02196 static const IClassFactoryVtbl HandlerClassFactoryVtbl = { 02197 HandlerCF_QueryInterface, 02198 HandlerCF_AddRef, 02199 HandlerCF_Release, 02200 HandlerCF_CreateInstance, 02201 HandlerCF_LockServer 02202 }; 02203 02204 HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv) 02205 { 02206 HRESULT hr; 02207 HandlerCF *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This)); 02208 if (!This) return E_OUTOFMEMORY; 02209 This->IClassFactory_iface.lpVtbl = &HandlerClassFactoryVtbl; 02210 This->refs = 0; 02211 This->clsid = *rclsid; 02212 02213 hr = IUnknown_QueryInterface((IUnknown *)&This->IClassFactory_iface, riid, ppv); 02214 if (FAILED(hr)) 02215 HeapFree(GetProcessHeap(), 0, This); 02216 02217 return hr; 02218 } Generated on Sun May 27 2012 04:25:37 for ReactOS by
1.7.6.1
|