609 lines
15 KiB
C++
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);
|
|
}
|