ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

defaulthandler.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.