windows-nt/Source/XPSP1/NT/com/ole32/stg/exp/astgconn.cxx
2020-09-26 16:20:57 +08:00

609 lines
15 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1996.
//
// File: astgconn.cxx
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 03-Apr-96 PhilipLa Created
//
//----------------------------------------------------------------------------
#include "exphead.cxx"
#pragma hdrstop
#include "astgconn.hxx"
#include <filllkb.hxx>
#include <asyncerr.hxx>
SCODE CAsyncConnection::Init(IConnectionPointContainer *pCPC,
CAsyncConnection *pacParent)
{
SCODE sc = S_OK;
CConnectionPoint *pcpoint;
olAssert(_pdacp == NULL);
if (pacParent)
_dwAsyncFlags = pacParent->_dwAsyncFlags;
olMem(pcpoint = new CConnectionPoint());
olChk(pcpoint->Init());
if ((pacParent) && (_dwAsyncFlags & ASYNC_MODE_COMPATIBILITY))
{
pcpoint->SetParent(pacParent->_pdacp);
}
else
{
pcpoint->SetParent(NULL);
}
_pCPC = pCPC;
_pdacp = pcpoint;
EH_Err:
return sc;
}
SCODE CAsyncConnection::InitClone(IConnectionPointContainer *pCPC,
CAsyncConnection *pac)
{
SCODE sc = S_OK;
CConnectionPoint *pcpoint;
olAssert(pac != NULL);
_dwAsyncFlags = pac->_dwAsyncFlags;
olMem(pcpoint = new CConnectionPoint());
olChk(pcpoint->Init());
if (_dwAsyncFlags & ASYNC_MODE_COMPATIBILITY)
{
IDocfileAsyncConnectionPoint *pdacp;
if (FAILED(sc = pac->_pdacp->GetParent(&pdacp)))
{
delete pcpoint;
return sc;
}
pcpoint->SetParent(pdacp);
}
else
{
pcpoint->SetParent(NULL);
}
_pCPC = pCPC;
_pdacp = pcpoint;
EH_Err:
return sc;
}
SCODE CAsyncConnection::InitMarshal(IConnectionPointContainer *pCPC,
DWORD dwAsyncFlags,
IDocfileAsyncConnectionPoint *pdacp)
{
SCODE sc = S_OK;
_dwAsyncFlags = dwAsyncFlags;
_pCPC = pCPC;
_pdacp = pdacp;
if (_pdacp)
_pdacp->AddRef();
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnection::~CAsyncConnection, public
//
// Synopsis: Destructor
//
// Returns: Appropriate status code
//
// History: 03-Apr-96 PhilipLa Created
//
//----------------------------------------------------------------------------
CAsyncConnection::~CAsyncConnection()
{
olDebugOut((DEB_ITRACE,
"In CAsyncConnection::~CAsyncConnection:%p()\n", this));
//Note: _pdacp must be released outside of the tree mutex, which
// means we need to extract the pointer and release it elsewhere.
#if 0
if (_pdacp != NULL)
{
_pdacp->Release();
}
#endif
olDebugOut((DEB_ITRACE,
"Out CAsyncConnection::~CAsyncConnection\n"));
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnection::QueryInterface, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 01-Jan-96 SusiA Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CAsyncConnection::QueryInterface(REFIID iid, void **ppvObj)
{
SCODE sc = S_OK;
olDebugOut((DEB_TRACE,
"In CAsyncConnection::QueryInterface:%p()\n",
this));
*ppvObj = NULL;
if ((IsEqualIID(iid, IID_IUnknown)) ||
(IsEqualIID(iid, IID_IConnectionPoint)))
{
*ppvObj = (IConnectionPoint *)this;
CAsyncConnection::AddRef();
}
else
{
return E_NOINTERFACE;
}
olDebugOut((DEB_TRACE, "Out CAsyncConnection::QueryInterface\n"));
return ResultFromScode(sc);
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnection::AddRef, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 29-Dec-95 SusiA Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CAsyncConnection::AddRef(void)
{
ULONG ulRet;
olDebugOut((DEB_TRACE,
"In CAsyncConnection::AddRef:%p()\n",
this));
InterlockedIncrement(&_cReferences);
ulRet = _cReferences;
olDebugOut((DEB_TRACE, "Out CAsyncConnection::AddRef\n"));
return ulRet;
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnection::Release, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 30-Dec-95 SusiA Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CAsyncConnection::Release(void)
{
LONG lRet;
olDebugOut((DEB_TRACE,
"In CAsyncConnection::Release:%p()\n",
this));
olAssert(_cReferences > 0);
lRet = InterlockedDecrement(&_cReferences);
if (lRet == 0)
{
delete this;
}
else if (lRet < 0)
{
olAssert((lRet > 0) && "Connection point released too many times.");
lRet = 0;
}
olDebugOut((DEB_TRACE, "Out CAsyncConnection::Release\n"));
return (ULONG)lRet;
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnection::Notify, public
//
// Synopsis:
//
// Returns: Appropriate status code
//
// History: 14-Jan-96 SusiA Created
// 27-Feb-96 SusiA Moved from Async wrappers
//
//----------------------------------------------------------------------------
SCODE CAsyncConnection::Notify(SCODE scFailure,
ILockBytes *pilb,
CPerContext *ppc,
CSafeSem *pss)
{
SCODE sc = S_OK;
BOOL fAccurate = (scFailure == E_PENDING);
IFillInfo *pfi = ppc->GetFillInfo();
ULONG ulWaterMark;
ULONG ulFailurePoint;
HANDLE hNotifyEvent;
if (pfi != NULL)
{
pfi->GetFailureInfo(&ulWaterMark,
&ulFailurePoint);
pss->Release();
while (((sc = _pdacp->NotifySinks(ulWaterMark,
ulFailurePoint,
fAccurate,
STG_S_MONITORING)) == STG_S_BLOCK) ||
(sc == STG_S_MONITORING) ||
// S_OK is a synonym for STG_S_MONITORING
(sc == S_OK))
{
DWORD dwFlags;
// wait for an event to signal
hNotifyEvent = ppc->GetNotificationEvent();
WaitForSingleObject(hNotifyEvent, INFINITE);
pfi->GetTerminationStatus(&dwFlags);
// client terminated call?
if (dwFlags == TERMINATED_ABNORMAL)
{
return STG_E_INCOMPLETE;
}
// download is complete
else if (dwFlags == TERMINATED_NORMAL)
{
return S_OK;
}
else
{
//Note: Don't overwrite the failure point we recorded
// before, since it may have been changed by some
// other thread.
//Don't need to take the critical section here, since
//we don't care about the current failure point.
ULONG ulFailurePointCurrent;
pfi->GetFailureInfo(&ulWaterMark,
&ulFailurePointCurrent);
// all the data is available now
if (ulWaterMark >= ulFailurePoint)
{
//We don't care what the return value is, so send
//STG_S_BLOCK and all sinks will have fOwner == FALSE
_pdacp->NotifySinks(ulWaterMark,
ulFailurePoint,
fAccurate,
STG_S_BLOCK);
break;
}
}
}
}
if ((sc == STG_S_RETRYNOW) ||
(sc == STG_S_BLOCK) ||
(sc == STG_S_MONITORING))
{
return S_OK;
}
else return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnection::GetConnectionInterface, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 30-Dec-95 SusiA Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CAsyncConnection::GetConnectionInterface(IID *pIID)
{
olDebugOut((DEB_ITRACE,
"In CAsyncConnection::GetConnectionInterface:%p()\n",
this));
*pIID = IID_IProgressNotify;
olDebugOut((DEB_ITRACE, "Out CAsyncConnection::GetConnectionInterface\n"));
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnection::GetConnectionPointContainer, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 30-Dec-95 SusiA Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CAsyncConnection::GetConnectionPointContainer(
IConnectionPointContainer ** ppCPC)
{
olDebugOut((DEB_ITRACE,
"In CAsyncConnection::GetConnectionPointContainer:%p()\n",
this));
*ppCPC = _pCPC;
_pCPC->AddRef();
olDebugOut((DEB_ITRACE,
"Out CAsyncConnection::GetConnectionPointContainer\n"));
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnection::EnumConnections, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 30-Dec-95 SusiA Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CAsyncConnection::EnumConnections(
IEnumConnections **ppEnum)
{
olDebugOut((DEB_ITRACE, "In CAsyncConnection::EnumConnections:%p()\n", this));
olDebugOut((DEB_ITRACE, "Out CAsyncConnection::EnumConnections\n"));
return E_NOTIMPL;
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnection:: Advise, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 29-Dec-95 SusiA Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CAsyncConnection::Advise(IUnknown *pUnkSink,
DWORD *pdwCookie)
{
SCODE sc;
IProgressNotify *ppnSink;
olDebugOut((DEB_ITRACE, "In CAsyncConnection::Advise:%p()\n", this));
olChk(pUnkSink->QueryInterface(IID_IProgressNotify, (void **)&ppnSink));
sc = _pdacp->AddConnection(ppnSink, pdwCookie);
ppnSink->Release();
olDebugOut((DEB_ITRACE, "Out CAsyncConnection::Advise\n"));
EH_Err:
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnection::Unadvise, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 30-Dec-95 SusiA Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CAsyncConnection::Unadvise(DWORD dwCookie)
{
SCODE sc;
olDebugOut((DEB_ITRACE, "In CAsyncConnection::Unadvise:%p()\n", this));
sc = _pdacp->RemoveConnection(dwCookie);
olDebugOut((DEB_ITRACE, "Out CAsyncConnection::Unadvise\n"));
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnectionContainer::EnumConnectionPoints, public
//
// Synopsis: Return enumerator on connection points
//
// Arguments: [ppEnum] -- Return pointer of enumerator
//
// Returns: Appropriate status code
//
// History: 28-Dec-95 SusiA Created
//
//----------------------------------------------------------------------------
STDMETHODIMP CAsyncConnectionContainer::EnumConnectionPoints(
IEnumConnectionPoints **ppEnum)
{
olDebugOut((DEB_ITRACE,
"In CAsyncConnectionContainer::EnumConnectionPoints:%p()\n",
this));
olDebugOut((DEB_ITRACE,
"Out CAsyncConnectionContainer::EnumConnectionPoints\n"));
return E_NOTIMPL;
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnectionContainer::FindConnectionPoint, public
//
// Synopsis: Return a connection point given an IID
//
// Arguments: [iid] -- IID to return connection point for
// [ppCP] -- Return location for pointer
//
// Returns: Appropriate status code
//
// History: 28-Dec-95 SusiA Created
//
//----------------------------------------------------------------------------
STDMETHODIMP CAsyncConnectionContainer::FindConnectionPoint(
REFIID iid,
IConnectionPoint **ppCP)
{
olDebugOut((DEB_ITRACE,
"In CAsyncConnectionContainer::FindConnectionPoint:%p()\n",
this));
CAsyncConnection *pcp;
if (IsEqualIID(iid, IID_IProgressNotify))
{
pcp = &_cpoint;
}
else
{
*ppCP = NULL;
return E_NOINTERFACE;
}
pcp->AddRef();
*ppCP = pcp;
olDebugOut((DEB_ITRACE,
"Out CAsyncConnectionContainer::FindConnectionPoint\n"));
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnectionContainer::InitConnection, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// History: 10-Apr-96 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
SCODE CAsyncConnectionContainer::InitConnection(CAsyncConnection *pacParent)
{
return _cpoint.Init(this, pacParent);
}
//+---------------------------------------------------------------------------
//
// Member: CAsyncConnectionContainer::InitClone, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// History: 10-Apr-96 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
SCODE CAsyncConnectionContainer::InitClone(CAsyncConnection *pac)
{
return _cpoint.InitClone(this, pac);
}