[OLE32] Sync with Wine Staging 1.7.55. CORE-10536
[reactos.git] / reactos / dll / win32 / ole32 / defaulthandler.c
index e54bb25..4e5bb21 100644 (file)
@@ -61,7 +61,8 @@ enum storage_state
 enum object_state
 {
     object_state_not_running,
-    object_state_running
+    object_state_running,
+    object_state_deferred_close
 };
 
 /****************************************************************************
@@ -117,6 +118,7 @@ struct DefaultHandler
   /* IDataObject delegate */
   IDataObject *pDataDelegate;
   enum object_state object_state;
+  ULONG in_call;
 
   /* connection cookie for the advise on the delegate OLE object */
   DWORD dwAdvConn;
@@ -170,6 +172,20 @@ static inline BOOL object_is_running(DefaultHandler *This)
     return IRunnableObject_IsRunning(&This->IRunnableObject_iface);
 }
 
+static void DefaultHandler_Stop(DefaultHandler *This);
+
+static inline void start_object_call(DefaultHandler *This)
+{
+    This->in_call++;
+}
+
+static inline void end_object_call(DefaultHandler *This)
+{
+    This->in_call--;
+    if (This->in_call == 0 && This->object_state == object_state_deferred_close)
+        DefaultHandler_Stop( This );
+}
+
 /*********************************************************
  * Method implementation for the  non delegating IUnknown
  * part of the DefaultHandler class.
@@ -336,7 +352,11 @@ static HRESULT WINAPI DefaultHandler_SetClientSite(
   TRACE("(%p, %p)\n", iface, pClientSite);
 
   if (object_is_running(This))
+  {
+    start_object_call( This );
     hr = IOleObject_SetClientSite(This->pOleDelegate, pClientSite);
+    end_object_call( This );
+  }
 
   /*
    * Make sure we release the previous client site if there
@@ -399,7 +419,11 @@ static HRESULT WINAPI DefaultHandler_SetHostNames(
        debugstr_w(szContainerObj));
 
   if (object_is_running(This))
+  {
+    start_object_call( This );
     IOleObject_SetHostNames(This->pOleDelegate, szContainerApp, szContainerObj);
+    end_object_call( This );
+  }
 
   /* Be sure to cleanup before re-assigning the strings. */
   HeapFree( GetProcessHeap(), 0, This->containerApp );
@@ -445,17 +469,26 @@ static void release_delegates(DefaultHandler *This)
 /* undoes the work done by DefaultHandler_Run */
 static void DefaultHandler_Stop(DefaultHandler *This)
 {
-  if (!object_is_running(This))
+  IOleCacheControl *cache_ctrl;
+  HRESULT hr;
+
+  if (This->object_state == object_state_not_running)
     return;
 
-  IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
+  hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl );
+  if (SUCCEEDED(hr))
+  {
+    hr = IOleCacheControl_OnStop( cache_ctrl );
+    IOleCacheControl_Release( cache_ctrl );
+  }
 
-  /* FIXME: call IOleCache_OnStop */
+  IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
 
   if (This->dataAdviseHolder)
     DataAdviseHolder_OnDisconnect(This->dataAdviseHolder);
 
   This->object_state = object_state_not_running;
+  release_delegates( This );
 }
 
 /************************************************************************
@@ -478,10 +511,11 @@ static HRESULT WINAPI DefaultHandler_Close(
   if (!object_is_running(This))
     return S_OK;
 
+  start_object_call( This );
   hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
+  end_object_call( This );
 
   DefaultHandler_Stop(This);
-  release_delegates(This);
 
   return hr;
 }
@@ -499,16 +533,18 @@ static HRESULT WINAPI DefaultHandler_SetMoniker(
            IMoniker*          pmk)
 {
   DefaultHandler *This = impl_from_IOleObject(iface);
+  HRESULT hr = S_OK;
 
-  TRACE("(%p, %d, %p)\n",
-       iface,
-       dwWhichMoniker,
-       pmk);
+  TRACE("(%p, %d, %p)\n", iface, dwWhichMoniker, pmk);
 
   if (object_is_running(This))
-    return IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
+  {
+    start_object_call( This );
+    hr = IOleObject_SetMoniker(This->pOleDelegate, dwWhichMoniker, pmk);
+    end_object_call( This );
+  }
 
-  return S_OK;
+  return hr;
 }
 
 /************************************************************************
@@ -525,13 +561,19 @@ static HRESULT WINAPI DefaultHandler_GetMoniker(
            IMoniker**         ppmk)
 {
   DefaultHandler *This = impl_from_IOleObject(iface);
+  HRESULT hr;
 
   TRACE("(%p, %d, %d, %p)\n",
        iface, dwAssign, dwWhichMoniker, ppmk);
 
   if (object_is_running(This))
-    return IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
-                                 ppmk);
+  {
+    start_object_call( This );
+    hr = IOleObject_GetMoniker(This->pOleDelegate, dwAssign, dwWhichMoniker,
+                               ppmk);
+    end_object_call( This );
+    return hr;
+  }
 
   /* FIXME: dwWhichMoniker == OLEWHICHMK_CONTAINER only? */
   if (This->clientSite)
@@ -560,14 +602,20 @@ static HRESULT WINAPI DefaultHandler_InitFromData(
            DWORD              dwReserved)
 {
   DefaultHandler *This = impl_from_IOleObject(iface);
+  HRESULT hr = OLE_E_NOTRUNNING;
 
   TRACE("(%p, %p, %d, %d)\n",
        iface, pDataObject, fCreation, dwReserved);
 
   if (object_is_running(This))
-    return IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
+  {
+    start_object_call( This );
+    hr = IOleObject_InitFromData(This->pOleDelegate, pDataObject, fCreation,
                                   dwReserved);
-  return OLE_E_NOTRUNNING;
+    end_object_call( This );
+  }
+
+  return hr;
 }
 
 /************************************************************************
@@ -583,15 +631,20 @@ static HRESULT WINAPI DefaultHandler_GetClipboardData(
            IDataObject**      ppDataObject)
 {
   DefaultHandler *This = impl_from_IOleObject(iface);
+  HRESULT hr = OLE_E_NOTRUNNING;
 
   TRACE("(%p, %d, %p)\n",
        iface, dwReserved, ppDataObject);
 
   if (object_is_running(This))
-    return IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
+  {
+    start_object_call( This );
+    hr = IOleObject_GetClipboardData(This->pOleDelegate, dwReserved,
                                        ppDataObject);
+    end_object_call( This );
+  }
 
-  return OLE_E_NOTRUNNING;
+  return hr;
 }
 
 static HRESULT WINAPI DefaultHandler_DoVerb(
@@ -612,8 +665,12 @@ static HRESULT WINAPI DefaultHandler_DoVerb(
   hr = IRunnableObject_Run(pRunnableObj, NULL);
   if (FAILED(hr)) return hr;
 
-  return IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
+  start_object_call( This );
+  hr = IOleObject_DoVerb(This->pOleDelegate, iVerb, lpmsg, pActiveSite,
                            lindex, hwndParent, lprcPosRect);
+  end_object_call( This );
+
+  return hr;
 }
 
 /************************************************************************
@@ -634,7 +691,11 @@ static HRESULT WINAPI DefaultHandler_EnumVerbs(
   TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
 
   if (object_is_running(This))
+  {
+    start_object_call( This );
     hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
+    end_object_call( This );
+  }
 
   if (hr == OLE_S_USEREG)
     return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
@@ -646,6 +707,8 @@ static HRESULT WINAPI DefaultHandler_Update(
            IOleObject*        iface)
 {
     DefaultHandler *This = impl_from_IOleObject(iface);
+    HRESULT hr;
+
     TRACE("(%p)\n", iface);
 
     if (!object_is_running(This))
@@ -653,7 +716,12 @@ static HRESULT WINAPI DefaultHandler_Update(
         FIXME("Should run object\n");
         return E_NOTIMPL;
     }
-    return IOleObject_Update(This->pOleDelegate);
+
+    start_object_call( This );
+    hr = IOleObject_Update(This->pOleDelegate);
+    end_object_call( This );
+
+    return hr;
 }
 
 /************************************************************************
@@ -667,12 +735,17 @@ static HRESULT WINAPI DefaultHandler_IsUpToDate(
            IOleObject*        iface)
 {
     DefaultHandler *This = impl_from_IOleObject(iface);
+    HRESULT hr = OLE_E_NOTRUNNING;
     TRACE("(%p)\n", iface);
 
     if (object_is_running(This))
-        return IOleObject_IsUpToDate(This->pOleDelegate);
+    {
+        start_object_call( This );
+        hr = IOleObject_IsUpToDate(This->pOleDelegate);
+        end_object_call( This );
+    }
 
-    return OLE_E_NOTRUNNING;
+    return hr;
 }
 
 /************************************************************************
@@ -687,11 +760,17 @@ static HRESULT WINAPI DefaultHandler_GetUserClassID(
            CLSID*             pClsid)
 {
   DefaultHandler *This = impl_from_IOleObject(iface);
+  HRESULT hr;
 
   TRACE("(%p, %p)\n", iface, pClsid);
 
   if (object_is_running(This))
-    return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
+  {
+    start_object_call( This );
+    hr = IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
+    end_object_call( This );
+    return hr;
+  }
 
   if (!pClsid)
     return E_POINTER;
@@ -715,10 +794,16 @@ static HRESULT WINAPI DefaultHandler_GetUserType(
            LPOLESTR*          pszUserType)
 {
   DefaultHandler *This = impl_from_IOleObject(iface);
+  HRESULT hr;
 
   TRACE("(%p, %d, %p)\n", iface, dwFormOfType, pszUserType);
   if (object_is_running(This))
-    return IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
+  {
+    start_object_call( This );
+    hr = IOleObject_GetUserType(This->pOleDelegate, dwFormOfType, pszUserType);
+    end_object_call( This );
+    return hr;
+  }
 
   return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
 }
@@ -736,14 +821,19 @@ static HRESULT WINAPI DefaultHandler_SetExtent(
            SIZEL*             psizel)
 {
   DefaultHandler *This = impl_from_IOleObject(iface);
+  HRESULT hr = OLE_E_NOTRUNNING;
 
   TRACE("(%p, %x, (%d x %d))\n", iface,
         dwDrawAspect, psizel->cx, psizel->cy);
 
   if (object_is_running(This))
-    return IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
+  {
+    start_object_call( This );
+    hr = IOleObject_SetExtent(This->pOleDelegate, dwDrawAspect, psizel);
+    end_object_call( This );
+  }
 
-  return OLE_E_NOTRUNNING;
+  return hr;
 }
 
 /************************************************************************
@@ -768,7 +858,12 @@ static HRESULT WINAPI DefaultHandler_GetExtent(
   TRACE("(%p, %x, %p)\n", iface, dwDrawAspect, psizel);
 
   if (object_is_running(This))
-    return IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
+  {
+    start_object_call( This );
+    hres = IOleObject_GetExtent(This->pOleDelegate, dwDrawAspect, psizel);
+    end_object_call( This );
+    return hres;
+  }
 
   hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
   if (FAILED(hres))
@@ -898,7 +993,12 @@ static HRESULT WINAPI DefaultHandler_GetMiscStatus(
   TRACE("(%p, %x, %p)\n", iface, dwAspect, pdwStatus);
 
   if (object_is_running(This))
-    return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
+  {
+    start_object_call( This );
+    hres = IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
+    end_object_call( This );
+    return hres;
+  }
 
   hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
 
@@ -920,13 +1020,18 @@ static HRESULT WINAPI DefaultHandler_SetColorScheme(
            struct tagLOGPALETTE* pLogpal)
 {
   DefaultHandler *This = impl_from_IOleObject(iface);
+  HRESULT hr = OLE_E_NOTRUNNING;
 
   TRACE("(%p, %p))\n", iface, pLogpal);
 
   if (object_is_running(This))
-    return IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
+  {
+    start_object_call( This );
+    hr = IOleObject_SetColorScheme(This->pOleDelegate, pLogpal);
+    end_object_call( This );
+  }
 
-  return OLE_E_NOTRUNNING;
+  return hr;
 }
 
 /*********************************************************
@@ -1007,8 +1112,19 @@ static HRESULT WINAPI DefaultHandler_GetData(
 
   IDataObject_Release(cacheDataObject);
 
-  if (FAILED(hres) && This->pDataDelegate)
+  if (hres == S_OK) return hres;
+
+  if (object_is_running( This ))
+  {
+    start_object_call(This);
     hres = IDataObject_GetData(This->pDataDelegate, pformatetcIn, pmedium);
+    end_object_call(This);
+    if (hres == S_OK) return hres;
+  }
+
+  /* Query running state again, as the object may have closed during _GetData call */
+  if (!object_is_running( This ))
+    hres = OLE_E_NOTRUNNING;
 
   return hres;
 }
@@ -1053,8 +1169,19 @@ static HRESULT WINAPI DefaultHandler_QueryGetData(
 
   IDataObject_Release(cacheDataObject);
 
-  if (FAILED(hres) && This->pDataDelegate)
+  if (hres == S_OK) return hres;
+
+  if (object_is_running( This ))
+  {
+    start_object_call( This );
     hres = IDataObject_QueryGetData(This->pDataDelegate, pformatetc);
+    end_object_call( This );
+    if (hres == S_OK) return hres;
+  }
+
+  /* Query running state again, as the object may have closed during _QueryGetData call */
+  if (!object_is_running( This ))
+    hres = OLE_E_NOTRUNNING;
 
   return hres;
 }
@@ -1072,13 +1199,18 @@ static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
            LPFORMATETC      pformatetcOut)
 {
   DefaultHandler *This = impl_from_IDataObject(iface);
+  HRESULT hr;
 
   TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
 
-  if (!This->pDataDelegate)
+  if (!object_is_running( This ))
     return OLE_E_NOTRUNNING;
 
-  return IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
+  start_object_call( This );
+  hr = IDataObject_GetCanonicalFormatEtc(This->pDataDelegate, pformatetcIn, pformatetcOut);
+  end_object_call( This );
+
+  return hr;
 }
 
 /************************************************************************
@@ -1163,8 +1295,12 @@ static HRESULT WINAPI DefaultHandler_DAdvise(
   if (!This->dataAdviseHolder)
   {
     hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
-    if (SUCCEEDED(hres) && This->pDataDelegate)
+    if (SUCCEEDED(hres) && object_is_running( This ))
+    {
+      start_object_call( This );
       DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
+      end_object_call( This );
+    }
   }
 
   if (SUCCEEDED(hres))
@@ -1299,6 +1435,7 @@ static HRESULT WINAPI DefaultHandler_Run(
 {
   DefaultHandler *This = impl_from_IRunnableObject(iface);
   HRESULT hr;
+  IOleCacheControl *cache_ctrl;
 
   FIXME("(%p): semi-stub\n", pbc);
 
@@ -1313,49 +1450,59 @@ static HRESULT WINAPI DefaultHandler_Run(
   if (FAILED(hr))
     return hr;
 
-  This->object_state = object_state_running;
-
   hr = IOleObject_Advise(This->pOleDelegate, &This->IAdviseSink_iface, &This->dwAdvConn);
+  if (FAILED(hr)) goto fail;
 
-  if (SUCCEEDED(hr) && This->clientSite)
-    hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
-
-  if (SUCCEEDED(hr))
+  if (This->clientSite)
   {
-    IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
-                              (void **)&This->pPSDelegate);
-    if (This->pPSDelegate)
-    {
-      if(This->storage_state == storage_state_initialised)
-        hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage);
-      else if(This->storage_state == storage_state_loaded)
-        hr = IPersistStorage_Load(This->pPSDelegate, This->storage);
-    }
+    hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
+    if (FAILED(hr)) goto fail;
   }
 
-  if (SUCCEEDED(hr) && This->containerApp)
+  hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage,
+                                 (void **)&This->pPSDelegate);
+  if (FAILED(hr)) goto fail;
+
+  if (This->storage_state == storage_state_initialised)
+      hr = IPersistStorage_InitNew(This->pPSDelegate, This->storage);
+  else if (This->storage_state == storage_state_loaded)
+      hr = IPersistStorage_Load(This->pPSDelegate, This->storage);
+  if (FAILED(hr)) goto fail;
+
+  if (This->containerApp)
+  {
     hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp,
                                  This->containerObj);
+    if (FAILED(hr)) goto fail;
+  }
 
   /* FIXME: do more stuff here:
    * - IOleObject_GetMiscStatus
    * - IOleObject_GetMoniker
-   * - IOleCache_OnRun
    */
 
-  if (SUCCEEDED(hr))
-    hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
-                                   (void **)&This->pDataDelegate);
+  hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject,
+                                 (void **)&This->pDataDelegate);
+  if (FAILED(hr)) goto fail;
 
-  if (SUCCEEDED(hr) && This->dataAdviseHolder)
-    hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
+  This->object_state = object_state_running;
 
-  if (FAILED(hr))
+  if (This->dataAdviseHolder)
   {
-    DefaultHandler_Stop(This);
-    release_delegates(This);
+    hr = DataAdviseHolder_OnConnect(This->dataAdviseHolder, This->pDataDelegate);
+    if (FAILED(hr)) goto fail;
   }
 
+  hr = IUnknown_QueryInterface( This->dataCache, &IID_IOleCacheControl, (void **)&cache_ctrl );
+  if (FAILED(hr)) goto fail;
+  hr = IOleCacheControl_OnRun( cache_ctrl, This->pDataDelegate );
+  IOleCacheControl_Release( cache_ctrl );
+  if (FAILED(hr)) goto fail;
+
+  return hr;
+
+fail:
+  DefaultHandler_Stop(This);
   return hr;
 }
 
@@ -1485,10 +1632,15 @@ static void WINAPI DefaultHandler_IAdviseSink_OnClose(
     if (This->oleAdviseHolder)
         IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
 
-    DefaultHandler_Stop(This);
+    if(!This->in_call)
+        DefaultHandler_Stop(This);
+    else
+    {
+        TRACE("OnClose during call.  Deferring shutdown\n");
+        This->object_state = object_state_deferred_close;
+    }
 }
 
-
 /************************************************************************
  * DefaultHandler_IPersistStorage_QueryInterface
  *
@@ -1541,7 +1693,11 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_GetClassID(
     TRACE("(%p)->(%p)\n", iface, clsid);
 
     if(object_is_running(This))
+    {
+        start_object_call( This );
         hr = IPersistStorage_GetClassID(This->pPSDelegate, clsid);
+        end_object_call( This );
+    }
     else
         hr = IPersistStorage_GetClassID(This->dataCache_PersistStg, clsid);
 
@@ -1564,7 +1720,11 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_IsDirty(
     if(hr != S_FALSE) return hr;
 
     if(object_is_running(This))
+    {
+        start_object_call( This );
         hr = IPersistStorage_IsDirty(This->pPSDelegate);
+        end_object_call( This );
+    }
 
     return hr;
 }
@@ -1648,7 +1808,11 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_InitNew(
     hr = IPersistStorage_InitNew(This->dataCache_PersistStg, pStg);
 
     if(SUCCEEDED(hr) && object_is_running(This))
+    {
+        start_object_call( This );
         hr = IPersistStorage_InitNew(This->pPSDelegate, pStg);
+        end_object_call( This );
+    }
 
     if(SUCCEEDED(hr))
     {
@@ -1680,7 +1844,11 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_Load(
         hr = IPersistStorage_Load(This->dataCache_PersistStg, pStg);
 
     if(SUCCEEDED(hr) && object_is_running(This))
+    {
+        start_object_call( This );
         hr = IPersistStorage_Load(This->pPSDelegate, pStg);
+        end_object_call( This );
+    }
 
     if(SUCCEEDED(hr))
     {
@@ -1708,7 +1876,11 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_Save(
 
     hr = IPersistStorage_Save(This->dataCache_PersistStg, pStgSave, fSameAsLoad);
     if(SUCCEEDED(hr) && object_is_running(This))
+    {
+        start_object_call( This );
         hr = IPersistStorage_Save(This->pPSDelegate, pStgSave, fSameAsLoad);
+        end_object_call( This );
+    }
 
     return hr;
 }
@@ -1730,7 +1902,11 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_SaveCompleted(
     hr = IPersistStorage_SaveCompleted(This->dataCache_PersistStg, pStgNew);
 
     if(SUCCEEDED(hr) && object_is_running(This))
+    {
+        start_object_call( This );
         hr = IPersistStorage_SaveCompleted(This->pPSDelegate, pStgNew);
+        end_object_call( This );
+    }
 
     if(pStgNew)
     {
@@ -1759,7 +1935,11 @@ static HRESULT WINAPI DefaultHandler_IPersistStorage_HandsOffStorage(
     hr = IPersistStorage_HandsOffStorage(This->dataCache_PersistStg);
 
     if(SUCCEEDED(hr) && object_is_running(This))
+    {
+        start_object_call( This );
         hr = IPersistStorage_HandsOffStorage(This->pPSDelegate);
+        end_object_call( This );
+    }
 
     if(This->storage) IStorage_Release(This->storage);
     This->storage = NULL;
@@ -1940,6 +2120,7 @@ static DefaultHandler* DefaultHandler_Construct(
   This->pPSDelegate = NULL;
   This->pDataDelegate = NULL;
   This->object_state = object_state_not_running;
+  This->in_call = 0;
 
   This->dwAdvConn = 0;
   This->storage = NULL;
@@ -1984,7 +2165,6 @@ static void DefaultHandler_Destroy(
 
   /* release delegates */
   DefaultHandler_Stop(This);
-  release_delegates(This);
 
   HeapFree( GetProcessHeap(), 0, This->containerApp );
   This->containerApp = NULL;