summaryrefslogtreecommitdiffstats
path: root/private/ole32/com/dde/client/ddestg.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'private/ole32/com/dde/client/ddestg.cxx')
-rw-r--r--private/ole32/com/dde/client/ddestg.cxx529
1 files changed, 529 insertions, 0 deletions
diff --git a/private/ole32/com/dde/client/ddestg.cxx b/private/ole32/com/dde/client/ddestg.cxx
new file mode 100644
index 000000000..35a7e5f44
--- /dev/null
+++ b/private/ole32/com/dde/client/ddestg.cxx
@@ -0,0 +1,529 @@
+/*
+
+copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ ddeStg.cpp
+
+Abstract:
+
+ This module contains the DdeObject::PersistStg and
+ DdeObject::ProxyManager methods
+
+Author:
+
+ Srini Koppolu (srinik) 22-June-1992
+ Jason Fuller (jasonful) 24-July-1992
+
+*/
+
+#include "ddeproxy.h"
+ASSERTDATA
+
+
+/*
+ * IMPLEMENTATION of CPersistStgImpl methods
+ *
+ */
+
+
+STDUNKIMPL_FORDERIVED(DdeObject, PersistStgImpl)
+
+
+#pragma SEG(CDdeObject_CPersistStgImpl_GetClassID)
+STDMETHODIMP NC(CDdeObject,CPersistStgImpl)::GetClassID (CLSID FAR* pClassID)
+{
+ *pClassID = m_pDdeObject->m_clsid;
+ return NOERROR;
+}
+
+
+#pragma SEG(CDdeObject_CPersistStgImpl_IsDirty)
+STDMETHODIMP NC(CDdeObject,CPersistStgImpl)::IsDirty ()
+{
+ return NOERROR;
+}
+
+
+
+#pragma SEG(CDdeObject_CPersistStgImpl_InitNew)
+STDMETHODIMP NC(CDdeObject,CPersistStgImpl)::InitNew
+ (IStorage FAR* pstg)
+{
+ HRESULT hres;
+ intrDebugOut((DEB_ITRACE,
+ "DdeObejct::InitNew(%x,pstg=%x)\n",
+ this,
+ pstg));
+
+ if (hres = m_pDdeObject->PostSysCommand (m_pDdeObject->m_pSysChannel,
+ (LPSTR)&achStdNewDocument,
+ TRUE))
+ return hres;
+
+ if (hres = m_pDdeObject->m_ProxyMgr.Connect (IID_NULL, CLSID_NULL))
+ return hres;
+
+ RetErr (m_pDdeObject->TermConv (m_pDdeObject->m_pSysChannel));
+ if (m_pDdeObject->m_pstg)
+ {
+ m_pDdeObject->m_pstg->Release();
+ }
+ m_pDdeObject->m_pstg = pstg;
+ pstg->AddRef();
+ return hres;
+}
+
+
+
+#pragma SEG(CDdeObject_CPersistStgImpl_Load)
+STDMETHODIMP NC(CDdeObject,CPersistStgImpl)::Load (IStorage FAR* pstg)
+{
+ LPSTR lpBuf=NULL;
+ HANDLE hDdePoke = NULL;
+ DWORD dwSize;
+ CStmBufRead StmRead;
+ CStmBufRead StmReadItem;
+ HRESULT hresult;
+
+ intrDebugOut((DEB_ITRACE,"CDdeObject::Load(%x,pstg=%x)\n",this,pstg));
+
+ {
+
+ if (hresult = StmRead.OpenStream(pstg, OLE10_NATIVE_STREAM))
+ {
+ intrDebugOut((DEB_ITRACE,
+ "::Load(%x) OpenStream failed(%x)\n",
+ this,
+ hresult));
+ return hresult;
+ }
+
+
+ if (hresult = StmRead.Read(&dwSize, sizeof(DWORD)))
+ {
+ intrDebugOut((DEB_ITRACE,
+ "::Load(%x) StRead failed(%x)\n",
+ this,
+ hresult));
+
+ goto errRtn;
+ }
+
+
+ lpBuf = wAllocDdePokeBlock (dwSize, g_cfNative, &hDdePoke);
+
+ if (lpBuf == NULL)
+ {
+ intrDebugOut((DEB_ITRACE,
+ "::Load(%x) wAllocDdePokeBlock failed(%x)\n",
+ this,
+ hresult));
+
+ hresult = E_OUTOFMEMORY;
+ goto errRtn;
+ }
+
+ if (hresult = StmRead.Read(lpBuf, dwSize))
+ {
+ intrDebugOut((DEB_ITRACE,
+ "::Load(%x) StRead of cfNative failed(%x)\n",
+ this,
+ hresult));
+ goto errRtn;
+ }
+
+ if (m_pDdeObject->m_hNative)
+ {
+ GlobalFree (m_pDdeObject->m_hNative);
+ }
+ m_pDdeObject->m_hNative = wNewHandle (lpBuf, dwSize);
+
+ if (m_pDdeObject->m_hNative == NULL)
+ {
+ intrDebugOut((DEB_ITRACE,
+ "::Load(%x) m_hNative NULL\n",
+ this));
+ }
+ }
+
+ GlobalUnlock (hDdePoke); // done with lpBuf
+
+ if (hresult = m_pDdeObject->PostSysCommand (m_pDdeObject->m_pSysChannel,
+ (LPSTR)&achStdEditDocument,
+ FALSE))
+ {
+ intrDebugOut((DEB_ITRACE,
+ "::Load(%x) PostSysCommand %s failed (%x)\n",
+ this,
+ &achStdEditDocument,
+ hresult));
+ goto errRtn;
+ }
+
+
+ // Read Item Name, if there is one
+ if (NOERROR == StmReadItem.OpenStream(pstg, OLE10_ITEMNAME_STREAM))
+ {
+ LPSTR szItemName = NULL;
+
+ ErrRtnH (ReadStringStreamA (StmReadItem, &szItemName));
+ m_pDdeObject->ChangeItem (szItemName);
+ PubMemFree(szItemName);
+ }
+
+ if (hresult = m_pDdeObject->m_ProxyMgr.Connect (IID_NULL, CLSID_NULL))
+ {
+ intrDebugOut((DEB_ITRACE,
+ "::Load(%x) ProxyMgr.Connect failed(%x)\n",
+ this,
+ hresult));
+ goto errRtn;
+ }
+
+
+ if ((hresult = m_pDdeObject->Poke(m_pDdeObject->m_aItem, hDdePoke))
+ != NOERROR)
+ {
+ intrDebugOut((DEB_ITRACE,
+ "::Load(%x) Poke failed(%x)\n",
+ this,
+ hresult));
+
+ // the Poke calls frees the Poke data even in case of failure.
+#ifdef LATER
+
+ if (hresult = m_pDdeObject->Execute (m_pDdeObject->m_pDocChannel,
+ wNewHandle ((LPSTR)achStdCloseDocument,sizeof(achStdCloseDocument)));
+ goto errDoc;
+#elseif
+ goto errDoc;
+#endif
+ }
+
+ hresult = m_pDdeObject->TermConv (m_pDdeObject->m_pSysChannel);
+ if (hresult != NOERROR)
+ {
+ intrDebugOut((DEB_ITRACE,
+ "::Load(%x) TermConv on SysChannel failed(%x)\n",
+ this,
+ hresult));
+ goto errRtn;
+ }
+
+
+ if (m_pDdeObject->m_pstg)
+ {
+ m_pDdeObject->m_pstg->Release();
+ }
+
+ m_pDdeObject->m_pstg = pstg;
+ pstg->AddRef();
+ goto LExit;
+
+errRtn:
+ if (hDdePoke)
+ GlobalFree (hDdePoke);
+ if (m_pDdeObject->m_pDocChannel)
+ m_pDdeObject->TermConv (m_pDdeObject->m_pDocChannel);
+LExit:
+ StmReadItem.Release();
+ StmRead.Release();
+
+ intrDebugOut((DEB_ITRACE,"::Load(%x) returning (%x)\n",this,hresult));
+ return hresult;
+}
+
+
+#pragma SEG(CDdeObject_CPersistStgImpl_Save)
+STDMETHODIMP NC(CDdeObject,CPersistStgImpl)::Save
+ (IStorage FAR* pstgSave, BOOL fSameAsLoad)
+{
+ intrDebugOut((DEB_ITRACE,
+ "DdeObject::Save(%x,pstgSave=%x)\n",
+ this,
+ pstgSave));
+
+
+ HRESULT hresult=NOERROR;
+
+ if (m_pDdeObject->m_fUpdateOnSave
+ && (m_pDdeObject->m_clsid != CLSID_Package
+ || m_pDdeObject->m_hNative == NULL))
+ {
+ // Get latest data from server, if it is not shutting down
+ // or telling us to Save, in which case it just gave us data.
+ // (If it is shutting down, it probably won't respond.
+ // Draw does respond, but gives bad data.)
+ // Packager gives truncated native data (header info with no
+ // actual embedded file) if you DDE_REQUEST it. Bug 3103
+ m_pDdeObject->Update (FALSE);
+ }
+
+ if (m_pDdeObject->m_hNative == NULL)
+ {
+ // we still have nothing to save
+ return ResultFromScode (E_BLANK);
+ }
+
+ hresult = m_pDdeObject->Save (pstgSave);
+
+ Puts ("PersistStg::Save done\n");
+ return hresult;
+}
+
+
+#pragma SEG(CDdeObject_CPersistStgImpl_SaveCompleted)
+STDMETHODIMP NC(CDdeObject,CPersistStgImpl)::SaveCompleted
+ (IStorage FAR* pstgNew)
+{
+ intrDebugOut((DEB_ITRACE,
+ "DdeObejct::SaveCompleted(%x,pstgNew=%x)\n",
+ this,
+ pstgNew));
+
+ RetZ (m_pDdeObject->m_pOleAdvHolder);
+ m_pDdeObject->m_pOleAdvHolder->SendOnSave();
+ if (pstgNew)
+ {
+ if (m_pDdeObject->m_pstg)
+ m_pDdeObject->m_pstg->Release();
+ m_pDdeObject->m_pstg = pstgNew;
+ pstgNew->AddRef();
+ }
+ return NOERROR;
+}
+
+
+#pragma SEG(CDdeObject_CPersistStgImpl_HandsOffStorage)
+STDMETHODIMP NC(CDdeObject,CPersistStgImpl)::HandsOffStorage(void)
+{
+ intrDebugOut((DEB_ITRACE,"DdeObejct::HandsOffStorage(%x)\n",this));
+ if (m_pDdeObject->m_pstg)
+ {
+ m_pDdeObject->m_pstg->Release();
+ m_pDdeObject->m_pstg = NULL;
+ }
+ return NOERROR;
+}
+
+
+/*
+ * IMPLEMENTATION of CProxyManagerImpl methods
+ *
+ */
+
+
+STDUNKIMPL_FORDERIVED(DdeObject, ProxyManagerImpl)
+
+
+
+#pragma SEG(CDdeObject_CProxyManagerImpl_CreateServer)
+STDMETHODIMP NC(CDdeObject, CProxyManagerImpl)::CreateServer(REFCLSID rclsid,
+ DWORD clsctx,
+ void *pv)
+{
+ intrDebugOut((DEB_ITRACE,"DdeObejct::CreateServer(%x)\n",this));
+ HRESULT hresult = NOERROR;
+
+ if (m_pDdeObject->m_pSysChannel)
+ {
+ intrDebugOut((DEB_ITRACE,
+ "::CreateServer(%x)m_pSysChannel exists\n",
+ this));
+ return NOERROR;
+ }
+
+ if (m_pDdeObject->m_aExeName == NULL)
+ {
+ intrDebugOut((DEB_ITRACE,
+ "::CreateServer(%x) Class Not Registered\n",
+ this));
+ return(REGDB_E_CLASSNOTREG);
+ }
+
+
+ if (!m_pDdeObject->AllocDdeChannel(&m_pDdeObject->m_pSysChannel,TRUE))
+ {
+ intrDebugOut((DEB_ITRACE,
+ "::CreateServer(%x)AllocDdeChannel is failing\n",
+ this));
+ return ReportResult(0, E_OUTOFMEMORY,0,0);
+ }
+
+ if (!m_pDdeObject->InitSysConv())
+ {
+ if (!(m_pDdeObject->LaunchApp()))
+ {
+ intrDebugOut((DEB_IERROR,"::CreateServer Could not launch app\n"));
+ hresult = ResultFromScode (CO_E_APPNOTFOUND);
+ goto errRtn;
+ }
+
+ if (!m_pDdeObject->InitSysConv())
+ {
+ intrDebugOut((DEB_IERROR,"::CreateServer Second init failed\n"));
+ hresult = ResultFromScode (CO_E_APPDIDNTREG);
+ goto errRtn;
+ }
+ }
+
+ return NOERROR;
+
+errRtn:
+ intrDebugOut((DEB_ITRACE,"DdeObejct::CreateServer(%x) is failing(%x)\n",this,hresult));
+ m_pDdeObject->DeleteChannel (m_pDdeObject->m_pSysChannel);
+ Assert (hresult != NOERROR); // This is an error path
+ return hresult;
+
+}
+
+
+#pragma SEG(CDdeObject_CProxyManagerImpl_Connect)
+STDMETHODIMP NC(CDdeObject, CProxyManagerImpl)::Connect(GUID oid, REFCLSID rclsid)
+{
+ intrDebugOut((DEB_ITRACE,"DdeObject::Connect(%x)\n",this));
+
+ if (m_pDdeObject->m_pDocChannel)
+ return NOERROR;
+
+ if (!m_pDdeObject->AllocDdeChannel (&m_pDdeObject->m_pDocChannel,FALSE))
+ {
+ intrDebugOut((DEB_ITRACE,
+ "::Connect(%x) AllocDdeChannel failed, return E_OUTOFMEMORY\n",
+ this));
+ return ReportResult(0, E_OUTOFMEMORY,0,0);
+ }
+
+ // Bug 3701
+ m_pDdeObject->m_fDidSendOnClose = FALSE;
+ if (wInitiate (m_pDdeObject->m_pDocChannel, m_pDdeObject->m_aClass,
+ m_pDdeObject->m_aTopic))
+ {
+ return NOERROR;
+ }
+
+ intrDebugOut((DEB_ITRACE,"::Connect(%x) wInitiate failed\n",this));
+ m_pDdeObject->DeleteChannel (m_pDdeObject->m_pDocChannel);
+ return ResultFromScode (E_FAIL);
+}
+
+
+#pragma SEG(CDdeObject_CProxyManagerImpl_LockConnection)
+STDMETHODIMP NC(CDdeObject, CProxyManagerImpl)::LockConnection(BOOL fLock, BOOL fLastUnlockReleases)
+{
+ intrDebugOut((DEB_ITRACE,
+ "DdeObject::LockConnection(%x,fLock=%x,fLastUnlockReleases=%x)\n",
+ this,
+ fLock,
+ fLastUnlockReleases));
+
+ if (fLock)
+ m_pDdeObject->m_cLocks++;
+ else
+ {
+ if (m_pDdeObject->m_cLocks!=0 && 0 == --m_pDdeObject->m_cLocks &&
+ fLastUnlockReleases && !m_pDdeObject->m_fVisible)
+ (void)m_pDdeObject->m_Ole.Close (OLECLOSE_SAVEIFDIRTY);
+ }
+ return NOERROR;
+}
+
+
+#ifdef NOTNEEDED
+#pragma SEG(CDdeObject_CProxyManagerImpl_GetClassID)
+STDMETHODIMP_(void) NC(CDdeObject, CProxyManagerImpl)::GetClassID(CLSID FAR* pClsid)
+{
+ *pClsid = m_pDdeObject->m_clsid;
+}
+
+
+#pragma SEG(CDdeObject_CProxyManagerImpl_GetOID)
+STDMETHODIMP_(OID) NC(CDdeObject, CProxyManagerImpl)::GetOID()
+{
+ if (m_pDdeObject->m_pSysChannel)
+ return (OID) m_pDdeObject->m_pSysChannel;
+
+ if (m_pDdeObject->m_pDocChannel)
+ return (OID) m_pDdeObject->m_pDocChannel;
+
+ return NULL;
+}
+#endif
+
+#pragma SEG(CDdeObject_CProxyManagerImpl_IsConnected)
+STDMETHODIMP_(BOOL) NC(CDdeObject, CProxyManagerImpl)::IsConnected(void)
+{
+ return m_pDdeObject->m_pDocChannel != NULL;
+}
+
+
+#pragma SEG(CDdeObject_CProxyManagerImpl_EstablishIID)
+STDMETHODIMP NC(CDdeObject, CProxyManagerImpl)::EstablishIID(REFIID iid, LPVOID FAR* ppv)
+{
+ // REVIEW: this is correct, but can we be smarter like in the real PM?
+ return QueryInterface(iid, ppv);
+}
+
+
+#pragma SEG(wTerminateIsComing)
+INTERNAL_(BOOL) wTerminateIsComing (LPDDE_CHANNEL pChannel)
+{
+ MSG msg;
+ return SSPeekMessage (&msg, pChannel->hwndCli, 0, 0, PM_NOREMOVE)
+ && msg.message == WM_DDE_TERMINATE
+ && (HWND)msg.wParam==pChannel->hwndSvr;
+}
+
+
+#pragma SEG(CDdeObject_CProxyManagerImpl_Disconnect)
+STDMETHODIMP_(void) NC(CDdeObject, CProxyManagerImpl)::Disconnect()
+{
+ intrDebugOut((DEB_ITRACE,"DdeObject::Disonnect(%x)\n",this));
+
+ if (m_pDdeObject->m_pDocChannel)
+ {
+ BOOL fTermComing = wTerminateIsComing (m_pDdeObject->m_pDocChannel);
+ if ((!m_pDdeObject->m_fNoStdCloseDoc
+ || (!m_pDdeObject->m_fWasEverVisible // invisible update or
+ && !m_pDdeObject->m_fDidGetObject // link from file case.
+ && m_pDdeObject->m_fDidStdOpenDoc)) // only do StdClose if did StdOpen
+ && !m_pDdeObject->m_fDidStdCloseDoc
+ && !fTermComing)
+ {
+ m_pDdeObject->Execute (m_pDdeObject->m_pDocChannel,
+ wNewHandle ((LPSTR)&achStdCloseDocument,sizeof(achStdCloseDocument)),
+ /*fStdClose*/TRUE,
+ /*fWait*/TRUE,
+ /*fDetectTerminate*/TRUE);
+
+ m_pDdeObject->m_fDidStdCloseDoc = TRUE;
+ }
+ if (!m_pDdeObject->m_fDidSendOnClose /*|| fTermComing*/)
+ {
+ // if we did not call SendOnClose() then Disconnect() was called
+ // by a Release method, not by SendOnClose().
+ // This happens when user deletes object in container.
+ BOOL fVisible = m_pDdeObject->m_fWasEverVisible; // TermConv clears this flag
+ m_pDdeObject->TermConv (m_pDdeObject->m_pDocChannel);
+ if (!fVisible)
+ m_pDdeObject->MaybeUnlaunchApp();
+ }
+ }
+
+ if (m_pDdeObject->m_pSysChannel)
+ {
+ intrDebugOut((DEB_IWARN,"Terminating system conversation in Disconnect()\n"));
+ // This should never happen, I think.
+ m_pDdeObject->TermConv (m_pDdeObject->m_pSysChannel);
+ }
+}
+STDMETHODIMP NC(CDdeObject, CProxyManagerImpl)::CreateServerWithHandler (REFCLSID rclsid, DWORD clsctx, void *pv,
+ REFCLSID rclsidHandler, IID iidSrv, void **ppv,
+ IID iidClnt, void *pClientSiteInterface)
+{
+ return E_NOTIMPL;
+}
+
+