//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1995. // // File: stgconn.cxx // // Contents: Connection points for Async Storage/Stream Wrappers // // Classes: // // Functions: // // History: 19-Dec-95 SusiA Created // //---------------------------------------------------------------------------- #include "astghead.cxx" #pragma hdrstop #include "stgwrap.hxx" //+--------------------------------------------------------------------------- // // Member: CConnectionPoint::CConnectionPoint, public // // Synopsis: Constructor // // Arguments: // // History: 28-Dec-95 SusiA Created // //---------------------------------------------------------------------------- CConnectionPoint::CConnectionPoint() { astgDebugOut((DEB_ITRACE, "In CConnectionPoint::CConnectionPoint:%p()\n", this)); _cReferences = 1; _dwCookie = 0; _pSinkHead = NULL; astgDebugOut((DEB_ITRACE, "Out CConnectionPoint::CConnectionPoint\n")); } void CConnectionPoint::Init(IConnectionPointContainer *pCPC) { _pCPC = pCPC; } //+--------------------------------------------------------------------------- // // Member: CConnectionPoint::QueryInterface, public // // Synopsis: // // Arguments: // // Returns: Appropriate status code // // Modifies: // // History: 01-Jan-96 SusiA Created // // Notes: // //---------------------------------------------------------------------------- STDMETHODIMP CConnectionPoint::QueryInterface(REFIID iid, void **ppvObj) { SCODE sc = S_OK; astgDebugOut((DEB_TRACE, "In CConnectionPoint::QueryInterface:%p()\n", this)); *ppvObj = NULL; if ((IsEqualIID(iid, IID_IUnknown)) || (IsEqualIID(iid, IID_IConnectionPoint))) { *ppvObj = (IConnectionPoint *)this; CConnectionPoint::AddRef(); } else { return E_NOINTERFACE; } astgDebugOut((DEB_TRACE, "Out CConnectionPoint::QueryInterface\n")); return ResultFromScode(sc); } //+--------------------------------------------------------------------------- // // Member: CConnectionPoint::AddRef, public // // Synopsis: // // Arguments: // // Returns: Appropriate status code // // Modifies: // // History: 29-Dec-95 SusiA Created // // Notes: // //---------------------------------------------------------------------------- STDMETHODIMP_(ULONG) CConnectionPoint::AddRef(void) { ULONG ulRet; astgDebugOut((DEB_TRACE, "In CConnectionPoint::AddRef:%p()\n", this)); InterlockedIncrement(&_cReferences); ulRet = _cReferences; astgDebugOut((DEB_TRACE, "Out CConnectionPoint::AddRef\n")); return ulRet; } //+--------------------------------------------------------------------------- // // Member: CConnectionPoint::Release, public // // Synopsis: // // Arguments: // // Returns: Appropriate status code // // Modifies: // // History: 30-Dec-95 SusiA Created // // Notes: // //---------------------------------------------------------------------------- STDMETHODIMP_(ULONG) CConnectionPoint::Release(void) { LONG lRet; astgDebugOut((DEB_TRACE, "In CConnectionPoint::Release:%p()\n", this)); astgAssert(_cReferences > 0); lRet = InterlockedDecrement(&_cReferences); if (lRet == 0) { astgAssert((lRet > 0) && "Connection point released too many times."); } else if (lRet < 0) lRet = 0; astgDebugOut((DEB_TRACE, "Out CConnectionPoint::Release\n")); return (ULONG)lRet; } //+--------------------------------------------------------------------------- // // Member: CConnectionPoint::GetConnectionInterface, public // // Synopsis: // // Arguments: // // Returns: Appropriate status code // // Modifies: // // History: 30-Dec-95 SusiA Created // // Notes: // //---------------------------------------------------------------------------- STDMETHODIMP CConnectionPoint::GetConnectionInterface(IID *pIID) { astgDebugOut((DEB_ITRACE, "In CConnectionPoint::GetConnectionInterface:%p()\n", this)); *pIID = IID_IProgressNotify; astgDebugOut((DEB_ITRACE, "Out CConnectionPoint::GetConnectionInterface\n")); return S_OK; } //+--------------------------------------------------------------------------- // // Member: CConnectionPoint::GetConnectionPointContainer, public // // Synopsis: // // Arguments: // // Returns: Appropriate status code // // Modifies: // // History: 30-Dec-95 SusiA Created // // Notes: // //---------------------------------------------------------------------------- STDMETHODIMP CConnectionPoint::GetConnectionPointContainer( IConnectionPointContainer ** ppCPC) { astgDebugOut((DEB_ITRACE, "In CConnectionPoint::GetConnectionPointContainer:%p()\n", this)); *ppCPC = _pCPC; _pCPC->AddRef(); astgDebugOut((DEB_ITRACE, "Out CConnectionPoint::GetConnectionPointContainer\n")); return S_OK; } //+--------------------------------------------------------------------------- // // Member: CConnectionPoint::Advise, public // // Synopsis: // // Arguments: // // Returns: Appropriate status code // // Modifies: // // History: 29-Dec-95 SusiA Created // // Notes: // //---------------------------------------------------------------------------- STDMETHODIMP CConnectionPoint::Advise(IUnknown *pUnkSink, DWORD *pdwCookie) { SCODE sc; CSinkList *pslTemp = NULL; CSinkList **ppslHead = NULL; void *pv = NULL; astgDebugOut((DEB_ITRACE, "In CConnectionPoint::Advise:%p()\n", this)); IProgressNotify *ppn; // for the sweeper release, only one Advise sink per storage/Stream will be allowed if (_pSinkHead != NULL) return E_UNEXPECTED; //BUGBUG: Multithread access astgMem(pslTemp = new CSinkList); //Note: The QueryInterface will give us a reference to hold on to. astgChk(pUnkSink->QueryInterface(IID_IProgressNotify, &pv)); pslTemp->SetProgressNotify((IProgressNotify *)pv); pslTemp->SetNext(_pSinkHead); *pdwCookie = ++_dwCookie; pslTemp->SetCookie(*pdwCookie); _pSinkHead = pslTemp; astgDebugOut((DEB_ITRACE, "Out CConnectionPoint::Advise\n")); return sc; Err: delete pslTemp; return sc; } //+--------------------------------------------------------------------------- // // Member: CConnectionPoint::Unadvise, public // // Synopsis: // // Arguments: // // Returns: Appropriate status code // // Modifies: // // History: 30-Dec-95 SusiA Created // // Notes: // //---------------------------------------------------------------------------- STDMETHODIMP CConnectionPoint::Unadvise(DWORD dwCookie) { CSinkList *pslTemp; CSinkList *pslPrev; astgDebugOut((DEB_ITRACE, "In CConnectionPoint::Unadvise:%p()\n", this)); pslTemp = _pSinkHead; pslPrev = NULL; while ((pslTemp != NULL) && (pslTemp->GetCookie() != dwCookie)) { pslPrev = pslTemp; pslTemp = pslTemp->GetNext(); } if (pslTemp != NULL) { //Found the sink. Delete it from the list. if (pslPrev != NULL) { pslPrev->SetNext(pslTemp->GetNext()); } else { _pSinkHead = pslTemp->GetNext(); } pslTemp->GetProgressNotify()->Release(); delete pslTemp; } else //Client passed in unknown cookie. return E_UNEXPECTED; astgDebugOut((DEB_ITRACE, "Out CConnectionPoint::Unadvise\n")); return S_OK; } //+--------------------------------------------------------------------------- // // Member: CConnectionPoint::EnumConnections, public // // Synopsis: // // Arguments: // // Returns: Appropriate status code // // Modifies: // // History: 30-Dec-95 SusiA Created // // Notes: // //---------------------------------------------------------------------------- STDMETHODIMP CConnectionPoint::EnumConnections( IEnumConnections **ppEnum) { astgDebugOut((DEB_ITRACE, "In CConnectionPoint::EnumConnections:%p()\n", this)); astgDebugOut((DEB_ITRACE, "Out CConnectionPoint::EnumConnections\n")); return E_NOTIMPL; }