//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1995. // // File: defsrv.cpp // // Contents: // // Classes: // // Functions: // // History: 10-19-95 JohannP (Johann Posch) Created // //---------------------------------------------------------------------------- #include #ifdef SERVER_HANDLER #include #include #include #include "defhndlr.h" #include "defutil.h" #include "ole1cls.h" #ifdef _DEBUG #include #endif // _DEBUG ASSERTDATA //+--------------------------------------------------------------------------- // // Method: CDefObject::SrvInitialize // // Synopsis: // // Arguments: [void] -- // // Returns: // // History: 10-19-95 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- HRESULT CDefObject::SrvInitialize(void) { HRESULT hresult = NOERROR; VDATEHEAP(); HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::Initialize\n", this)); CLSID clsidsrv = CLSID_ServerHandler; Assert (( CanUseServerHandler() )); Assert((m_pProxyMgr != NULL)); if (CanUseClientSiteHandler()) { hresult = CreateClientSiteHandler(m_pAppClientSite, &_pClientSiteHandler); if (FAILED(hresult)) { _pClientSiteHandler = NULL; } Assert((_pClientSiteHandler != NULL)); } hresult = m_pProxyMgr->CreateServerWithHandler(m_clsidServer, CLSCTX_LOCAL_SERVER, NULL,clsidsrv, IID_IServerHandler, (void **) &_pSrvHndlr, IID_IClientSiteHandler, _pClientSiteHandler); if (SUCCEEDED(hresult)) { // set up the server handler and call InitializeAndRun on it Assert((_pSrvHndlr != NULL)); } else { // try to get server without server handler object _dwClientSiteHandler = 0; _dwServerHandler = 0; // release the client handler if (_pClientSiteHandler) { _pClientSiteHandler->Release(); _pClientSiteHandler = NULL; } // Note: do not try to launch the server without handler here // this will be done by the default handler } HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::SrvInitialize\n", this)); return hresult; } //+--------------------------------------------------------------------------- // // Method: CDefObject::SrvRun // // Synopsis: // // Arguments: [void] -- // // Returns: // // History: 10-19-95 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- HRESULT CDefObject::SrvRun(void) { HRESULT hresult = NOERROR; VDATEHEAP(); HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::SrvRun\n", this)); INSRVRUN InSrvRun; OUTSRVRUN *pOutSrvRun = NULL; BOOL fLockedContainer; IMoniker *pmk; memset((void*)&InSrvRun, 0, sizeof(InSrvRun)); Assert((_pSrvHndlr)); // get the Container and lock it // NOTE: the lock state of the proxy mgr is not changed; it remembers // the state and sets up the connection correctly. // server is running; normally this coincides with locking the // container, but we keep a separate flag since locking the container // may fail. m_flags |= DH_FORCED_RUNNING; // Lock the container fLockedContainer = m_flags & DH_LOCKED_CONTAINER; DuLockContainer(m_pAppClientSite, TRUE, &fLockedContainer ); if( fLockedContainer ) { m_flags |= DH_LOCKED_CONTAINER; } else { m_flags &= ~DH_LOCKED_CONTAINER; } // PStgDelegate Load or InitNew InSrvRun.dwInFlags = m_flags; InSrvRun.pStg = m_pStg; if (NULL == m_pPSDelegate) { InSrvRun.dwOperation |= OP_NeedPersistStorage; } if (NULL == m_pDataDelegate) { InSrvRun.dwOperation |= OP_NeedDataObject; } if (NULL == m_pOleDelegate) { InSrvRun.dwOperation |= OP_NeedOleObject; InSrvRun.dwOperation |= OP_NeedUserClassID; } // Set the clientsite if (m_pAppClientSite) { InSrvRun.dwOperation |= OP_GotClientSite; } // set the hostname InSrvRun.pszContainerApp = (LPOLESTR)m_pHostNames; InSrvRun.pszContainerObj = (LPOLESTR)(m_pHostNames + m_ibCntrObj); // adivse sink Assert((m_dwConnOle == 0L)); InSrvRun.pAS = (IAdviseSink *) &m_AdviseSink; InSrvRun.dwConnOle = m_dwConnOle; // Get the Moniker and call if(m_pAppClientSite != NULL) { if (m_pAppClientSite->GetMoniker (OLEGETMONIKER_ONLYIFTHERE,OLEWHICHMK_OBJREL, &pmk) == NOERROR) { AssertOutPtrIface(NOERROR, pmk); InSrvRun.pMnk = pmk; } else { InSrvRun.pMnk = NULL; } // QI for IMsoDocumentSite IUnknown *pMsoDS = NULL; hresult = m_pAppClientSite->QueryInterface( IID_IMsoDocumentSite, (void **)&pMsoDS); if (hresult == NOERROR) { // indicate we have MsoDocumentSite InSrvRun.dwOperation |= OP_HaveMsoDocumentSite; pMsoDS->Release(); } } // MAKE CALL TO SERVERHANDLER hresult = _pSrvHndlr->RunAndInitialize(&InSrvRun, &pOutSrvRun); if (SUCCEEDED(hresult)) { if (InSrvRun.dwOperation & OP_NeedPersistStorage) { Assert(NULL != pOutSrvRun->pPStg); m_pPSDelegate = pOutSrvRun->pPStg; } if (InSrvRun.dwOperation & OP_NeedDataObject) { Assert(NULL != pOutSrvRun->pDO); m_pDataDelegate = pOutSrvRun->pDO; // inform cache that we are running Assert(NULL != m_pCOleCache); m_pCOleCache->OnRun(m_pDataDelegate); // Enumerate all the advises we stored while we were either not // running or running the previous time, and send them to the // now-running object. Assert(NULL != m_pDataAdvCache); m_pDataAdvCache->EnumAndAdvise(m_pDataDelegate, TRUE); } if (InSrvRun.dwOperation & OP_NeedOleObject) { Assert(NULL != pOutSrvRun->pOO); m_pOleDelegate = pOutSrvRun->pOO; } if (InSrvRun.dwOperation & OP_NeedUserClassID) { Assert(NULL != pOutSrvRun->pUserClassID); m_clsidUser = *(pOutSrvRun->pUserClassID); } m_dwConnOle = pOutSrvRun->dwOutFlag; if (InSrvRun.pMnk != NULL) { InSrvRun.pMnk->Release(); } // release the pUnkOuter for all marshald pointers if (m_pPSDelegate && m_pUnkOuter) { m_pUnkOuter->Release(); } if (m_pOleDelegate && m_pUnkOuter) { m_pUnkOuter->Release(); } if (m_pDataDelegate && m_pUnkOuter) { m_pUnkOuter->Release(); } } else // Server Handler RunAndInitialize has failed... now clean up. { Stop(); // if for some reason we did not unlock the container by now, // do it (e.g., app crashed or failed during InitNew). fLockedContainer = (m_flags & DH_LOCKED_CONTAINER); DuLockContainer(m_pAppClientSite, FALSE, &fLockedContainer ); if( fLockedContainer ) { m_flags |= DH_LOCKED_CONTAINER; } else { m_flags &= ~DH_LOCKED_CONTAINER; } if (InSrvRun.pMnk != NULL) { InSrvRun.pMnk->Release(); } } if (pOutSrvRun != NULL) { PubMemFree(pOutSrvRun->pUserClassID); // OK to free NULL; PubMemFree(pOutSrvRun); } HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::SrvRun( %lx )\n", this, hresult)); return hresult; } //+--------------------------------------------------------------------------- // // Method: CDefObject::SrvRunAndDoVerb // // Synopsis: // // Arguments: [iVerb] -- // [lpmsg] -- // [pActiveSite] -- // [lindex] -- // [hwndParent] -- // [lprcPosRect] -- // // Returns: // // History: 10-19-95 JohannP (Johann Posch) Created // // Notes: This is not implemented yet. // //---------------------------------------------------------------------------- HRESULT CDefObject::SrvRunAndDoVerb( LONG iVerb, LPMSG lpmsg, LPOLECLIENTSITE pActiveSite, LONG lindex, HWND hwndParent, const RECT * lprcPosRect) { HRESULT hresult = NOERROR; VDATEHEAP(); HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::SrvRunAndDoVerb\n", this)); HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::SrvRunAndDoVerb\n", this)); return hresult; } //+--------------------------------------------------------------------------- // // Method: CDefObject::SrvDoVerb // // Synopsis: 1. gathers information on the client site // 2. calls the serverhandler with SrvDoverb with collected information // 3. serverhandler sets up connections and calls // OleObject::DoVerb on reall object // 4. release objects which did not get used // // Arguments: [iVerb] -- OleObject DoVerb parameter // [lpmsg] -- detto // [pActiveSite] -- detto // [lindex] -- detto // [hwndParent] -- detto // [lprcPosRect] -- detto // // Returns: // // History: 10-19-95 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- HRESULT CDefObject::SrvDoVerb( LONG iVerb, LPMSG lpmsg, LPOLECLIENTSITE pActiveSite, LONG lindex, HWND hwndParent, const RECT * lprcPosRect) { HRESULT hresult = NOERROR; VDATEHEAP(); HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::SrvDoVerb\n", this)); CInSrvRun InSrvRun; OUTSRVRUN *pOutSrvRun = NULL; IOleContainer *pOCont = NULL; IOleObject *pOOCont = NULL; IOleClientSite *pOContCS; IOleInPlaceSite *pOIPS; // set up the DoVerb parametes InSrvRun.dwOperation = 0; InSrvRun.iVerb = iVerb; InSrvRun.lpmsg = lpmsg; InSrvRun.lindex = lindex; InSrvRun.hwndParent = hwndParent; InSrvRun.lprcPosRect = (RECT *)lprcPosRect; // Step 1: set up OleClientSiteActive if (pActiveSite) { // Currently this Assert goes off with LE test = deflink-1854 (bchapman Mar'96) Assert(NULL != _pClientSiteHandler); _pClientSiteHandler->SetClientSiteDelegate(ID_ClientSiteActive, pActiveSite); InSrvRun.dwOperation |= OP_GotClientSiteActive; } // Step 2: IOleClientSite::GetContainer // Note: this call might cause a GetUserClassID call // to the server hresult = m_pAppClientSite->GetContainer(&pOCont); if (hresult == NOERROR) { HdlAssert((_pClientSiteHandler->_pOCont == NULL)); _pClientSiteHandler->_pOCont = pOCont; InSrvRun.dwOperation |= OP_GotContainer; // Step 3: QI on OleContainer for the OleObject hresult = pOCont->QueryInterface(IID_IOleObject, (void **)&pOOCont); if (hresult == NOERROR) { InSrvRun.dwOperation |= OP_GotOleObjectOfContainer; // release OleObject of container pOOCont->Release(); } } // Step 6: OI for IOleInPlaceSite hresult = m_pAppClientSite->QueryInterface(IID_IOleInPlaceSite, (void **)&pOIPS); if (hresult == NOERROR) { // set up OleInPlaceSite on the clientsitehandler HdlAssert((_pClientSiteHandler != NULL)); // release the old OleInPlaceSite if (_pClientSiteHandler->_pOIPS) { _pClientSiteHandler->_pOIPS->Release(); } _pClientSiteHandler->_pOIPS = pOIPS; // Step 7: IOleInPlaceSite::CanInPlaceActivate InSrvRun.dwInPlace = pOIPS->CanInPlaceActivate(); // indicate we have OleInPlaceSite InSrvRun.dwOperation |= OP_GotInPlaceSite; } // call the ServerHandler HdlDebugOut((DEB_SERVERHANDLER, "%p In CDefObject::SrvDoVerb calling DoVerb on ServerHandler!\n",this)); hresult = _pSrvHndlr->DoVerb(&InSrvRun, &pOutSrvRun); HdlDebugOut((DEB_SERVERHANDLER, "%p In CDefObject::SrvDoVerb return from DoVerb on ServerHandler!\n",this)); Assert(NULL != _pClientSiteHandler); if (FAILED(hresult)) { HdlDebugOut((DEB_ERROR, "OO::DoVerb failed !")); goto errRtn; } // Release the active OleClientSite if not used by server if ( (InSrvRun.dwOperation & OP_GotClientSiteActive) && !(pOutSrvRun->dwOperation & OP_GotClientSiteActive) ) { // release the active clientsite if not used by the server app. Assert(NULL != _pClientSiteHandler); _pClientSiteHandler->SetClientSiteDelegate(ID_ClientSiteActive, NULL); } // Release OleInPlaceSite if not used by server if ( (InSrvRun.dwOperation & OP_GotInPlaceSite) && !(pOutSrvRun->dwOperation & OP_GotInPlaceSite) ) { _pClientSiteHandler->SetClientSiteDelegate(ID_InPlaceSite,NULL); } // Release the container if not used by server if ( (InSrvRun.dwOperation & OP_GotContainer) && !(pOutSrvRun->dwOperation & OP_GotContainer) ) { _pClientSiteHandler->SetClientSiteDelegate(ID_Container,NULL); } errRtn: // delete the out parameter if (pOutSrvRun) { PubMemFree(pOutSrvRun); } HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::SrvDoVerb\n",this)); return hresult; } //+--------------------------------------------------------------------------- // // Method: CDefObject::SrvRelease // // Synopsis: // // Arguments: [void] -- // // Returns: // // History: 10-19-95 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- DWORD CDefObject::SrvRelease(void) { VDATEHEAP(); HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::SrvRelease\n", this)); Assert((_pSrvHndlr != NULL)); DWORD dwRet = _pSrvHndlr->Release(); #if DBG==1 if (dwRet) { HdlDebugOut((DEB_ERROR, "Last IServerHandler::Release() return %ld\n", dwRet)); } #endif _pSrvHndlr = NULL; HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::SrvRelease\n", this)); return dwRet; } //+--------------------------------------------------------------------------- // // Method: CDefObject::SrvCloseAndRelease // // Synopsis: // // Arguments: [dwFlag] -- // // Returns: // // History: 11-17-95 JohannP (Johann Posch) Created // // Notes: // //---------------------------------------------------------------------------- HRESULT CDefObject::SrvCloseAndRelease(DWORD dwFlag) { HRESULT hresult; VDATEHEAP(); HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::SrvCloseAndRelease\n", this)); HdlAssert((_pSrvHndlr != NULL)); hresult = _pSrvHndlr->CloseAndRelease(dwFlag); HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::SrvSrvCloseAndRelease hr:%lx\n",this,hresult)); return hresult; } //+--------------------------------------------------------------------------- // // Method: CDefObject::InitializeServerHandlerOptions // // Synopsis: // // Arguments: [clsidSrv] -- // // Returns: // // History: 11-17-95 JohannP (Johann Posch) Created // // Notes: determines server application specifics which can be used // to make serverhandler operations more efficient // Review: (JohannP) we would need a flag in the registery or so // //---------------------------------------------------------------------------- void CDefObject::InitializeServerHandlerOptions(REFCLSID clsidSrv) { VDATEHEAP(); HdlDebugOut((DEB_SERVERHANDLER, "%p _IN CDefObject::InitializeServerHandlerOptions\n",this)); // // this method should retrieve server application specific informantion // HdlDebugOut((DEB_SERVERHANDLER, "%p OUT CDefObject::InitializeServerHandlerOptions\n",this)); } #endif // SERVER_HANDLER