diff options
Diffstat (limited to 'private/ole32/com/dde/client/ddestg.cxx')
-rw-r--r-- | private/ole32/com/dde/client/ddestg.cxx | 529 |
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; +} + + |