NT4/private/ole32/stg/xact/xactenum.cxx
2020-09-30 17:12:29 +02:00

680 lines
15 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1994.
//
// File: xactenum.cxx
//
// Contents: CResourceEnum implementation
//
// Classes:
//
// Functions:
//
// History: 26-Jul-95 PhilipLa Created
//
//----------------------------------------------------------------------------
#include "xacthead.cxx"
#pragma hdrstop
#include "xactenum.hxx"
#include "coord.hxx"
#include "xactlist.hxx"
#include "xactdisp.hxx"
#if 0
//Instantiate so we can make sure that all the methods are
// properly declared.
CResourceEnum teFoo(NULL);
#endif
//BUGBUG: This code is generally not safe in the face of resources
// defecting while an enumeration is going on. This needs to
// be fixed.
//+---------------------------------------------------------------------------
//
// Member: CResourceEnum::CResourceEnum, public
//
// Synopsis: Constructor
//
// Arguments: [ptc] -- Pointer to transaction coordinator
//
// History: 26-Jul-95 PhilipLa Created
//
//----------------------------------------------------------------------------
CResourceEnum::CResourceEnum(CTransactionCoordinator *ptc)
{
xactDebugOut((DEB_ITRACE, "In CResourceEnum::CResourceEnum:%p()\n", this));
_ptc = ptc;
_ptc->AddRef();
Reset();
xactDebugOut((DEB_ITRACE, "Out CResourceEnum::CResourceEnum\n"));
}
//+---------------------------------------------------------------------------
//
// Member: CResourceEnum::~CResourceEnum, public
//
// Synopsis: Destructor
//
// Returns: Appropriate status code
//
// History: 26-Jul-95 PhilipLa Created
//
//----------------------------------------------------------------------------
CResourceEnum::~CResourceEnum()
{
xactDebugOut((DEB_ITRACE, "In CResourceEnum::~CResourceEnum:%p()\n", this));
_ptc->Release();
xactDebugOut((DEB_ITRACE, "Out CResourceEnum::~CResourceEnum\n"));
}
//+---------------------------------------------------------------------------
//
// Member: CResourceEnum::QueryInterface, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 05-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CResourceEnum::QueryInterface(REFIID iid, void **ppvObj)
{
SCODE sc = S_OK;
xactDebugOut((DEB_TRACE,
"In CResourceEnum::QueryInterface:%p()\n",
this));
*ppvObj = NULL;
if ((IsEqualIID(iid, IID_IUnknown)) || (IsEqualIID(iid, IID_IEnumXACTRE)))
{
*ppvObj = (IEnumXACTRE *)this;
CResourceEnum::AddRef();
}
else
{
sc = E_NOINTERFACE;
}
xactDebugOut((DEB_TRACE, "Out CResourceEnum::QueryInterface\n"));
return ResultFromScode(sc);
}
//+---------------------------------------------------------------------------
//
// Member: CResourceEnum::AddRef, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 05-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CResourceEnum::AddRef(void)
{
ULONG ulRet;
xactDebugOut((DEB_TRACE,
"In CResourceEnum::AddRef:%p()\n",
this));
InterlockedIncrement(&_cReferences);
ulRet = _cReferences;
xactDebugOut((DEB_TRACE, "Out CResourceEnum::AddRef\n"));
return ulRet;
}
//+---------------------------------------------------------------------------
//
// Member: CResourceEnum::Release, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 05-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CResourceEnum::Release(void)
{
LONG lRet;
xactDebugOut((DEB_TRACE,
"In CResourceEnum::Release:%p()\n",
this));
xactAssert(_cReferences > 0);
lRet = InterlockedDecrement(&_cReferences);
if (lRet == 0)
{
delete this;
}
else if (lRet < 0)
lRet = 0;
xactDebugOut((DEB_TRACE, "Out CResourceEnum::Release\n"));
return (ULONG)lRet;
}
//+---------------------------------------------------------------------------
//
// Member: CResourceEnum::Next, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 26-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CResourceEnum::Next(ULONG celt,
XACTRE *rgelt,
ULONG *pceltFetched)
{
xactDebugOut((DEB_ITRACE, "In CResourceEnum::Next:%p()\n", this));
SCODE sc = S_OK;
ULONG cFetched = 0;
XACTRE *pxCurrent = rgelt;
for (ULONG i = 0; (_pxlCurrent != NULL) && (i < celt); i++)
{
IUnknown *punk;
if (!_fSinglePhaseReturned)
{
_fSinglePhaseReturned = TRUE;
xactChk(_ptc->_pxlSinglePhase->GetTransaction()->
QueryInterface(IID_IUnknown,
(void **)&punk));
pxCurrent->type = XACTRETY_ONEPHASE;
pxCurrent->status = _ptc->_pxlSinglePhase->GetState();
pxCurrent->grfRMTC = _ptc->_pxlSinglePhase->GetFlags();
pxCurrent->rmgrid = *(_ptc->_pxlSinglePhase->GetRMGRID());
}
else
{
xactChk(_pxlCurrent->GetResource()->QueryInterface(IID_IUnknown,
(void **)&punk));
pxCurrent->type = XACTRETY_TWOPHASE;
pxCurrent->status = _pxlCurrent->GetState();
pxCurrent->grfRMTC = _pxlCurrent->GetFlags();
pxCurrent->rmgrid = *(_pxlCurrent->GetRMGRID());
_pxlCurrent = _pxlCurrent->GetNext();
}
pxCurrent->pResource = punk;
//Note: We don't release punk, since we want to return a reference
// to the caller.
cFetched++;
pxCurrent++;
}
if (pceltFetched != NULL)
{
*pceltFetched = cFetched;
}
xactDebugOut((DEB_ITRACE, "Out CResourceEnum::Next\n"));
return (cFetched == celt) ? S_OK : S_FALSE;
Err:
if (pceltFetched != NULL)
{
*pceltFetched = cFetched;
}
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CResourceEnum::Skip, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 26-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CResourceEnum::Skip(ULONG celt)
{
xactDebugOut((DEB_ITRACE, "In CResourceEnum::Skip:%p()\n", this));
for (ULONG i = 0; (_pxlCurrent != NULL) && (i < celt); i++)
{
_pxlCurrent = _pxlCurrent->GetNext();
}
xactDebugOut((DEB_ITRACE, "Out CResourceEnum::Skip\n"));
return (i == celt) ? S_OK : S_FALSE;
}
//+---------------------------------------------------------------------------
//
// Member: CResourceEnum::Reset, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 26-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CResourceEnum::Reset(void)
{
xactDebugOut((DEB_ITRACE, "In CResourceEnum::Reset:%p()\n", this));
_pxlCurrent = _ptc->_pxlResources;
_fSinglePhaseReturned = FALSE;
xactDebugOut((DEB_ITRACE, "Out CResourceEnum::Reset\n"));
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Member: CResourceEnum::Clone, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 26-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CResourceEnum::Clone(IEnumXACTRE **ppenum)
{
SCODE sc;
xactDebugOut((DEB_ITRACE, "In CResourceEnum::Clone:%p()\n", this));
CResourceEnum *pre;
xactMem(*ppenum = new CResourceEnum(_ptc));
((CResourceEnum *)(*ppenum))->_pxlCurrent = _pxlCurrent;
xactDebugOut((DEB_ITRACE, "Out CResourceEnum::Clone\n"));
Err:
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionEnum::CTransactionEnum, public
//
// Synopsis: Constructor
//
// Arguments: [ptc] -- Pointer to transaction coordinator
//
// History: 26-Jul-95 PhilipLa Created
//
//----------------------------------------------------------------------------
CTransactionEnum::CTransactionEnum(CTransactionDispenser *ptd)
{
xactDebugOut((DEB_ITRACE, "In CTransactionEnum::CTransactionEnum:%p()\n", this));
_ptd = ptd;
_ptd->AddRef();
Reset();
xactDebugOut((DEB_ITRACE, "Out CTransactionEnum::CTransactionEnum\n"));
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionEnum::~CTransactionEnum, public
//
// Synopsis: Destructor
//
// Returns: Appropriate status code
//
// History: 26-Jul-95 PhilipLa Created
//
//----------------------------------------------------------------------------
CTransactionEnum::~CTransactionEnum()
{
xactDebugOut((DEB_ITRACE, "In CTransactionEnum::~CTransactionEnum:%p()\n", this));
_ptd->Release();
xactDebugOut((DEB_ITRACE, "Out CTransactionEnum::~CTransactionEnum\n"));
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionEnum::QueryInterface, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 05-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CTransactionEnum::QueryInterface(REFIID iid, void **ppvObj)
{
SCODE sc = S_OK;
xactDebugOut((DEB_TRACE,
"In CTransactionEnum::QueryInterface:%p()\n",
this));
*ppvObj = NULL;
if ((IsEqualIID(iid, IID_IUnknown)) || (IsEqualIID(iid, IID_IEnumTransaction)))
{
*ppvObj = (IEnumTransaction *)this;
CTransactionEnum::AddRef();
}
else
{
sc = E_NOINTERFACE;
}
xactDebugOut((DEB_TRACE, "Out CTransactionEnum::QueryInterface\n"));
return ResultFromScode(sc);
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionEnum::AddRef, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 05-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CTransactionEnum::AddRef(void)
{
ULONG ulRet;
xactDebugOut((DEB_TRACE,
"In CTransactionEnum::AddRef:%p()\n",
this));
InterlockedIncrement(&_cReferences);
ulRet = _cReferences;
xactDebugOut((DEB_TRACE, "Out CTransactionEnum::AddRef\n"));
return ulRet;
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionEnum::Release, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 05-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CTransactionEnum::Release(void)
{
LONG lRet;
xactDebugOut((DEB_TRACE,
"In CTransactionEnum::Release:%p()\n",
this));
xactAssert(_cReferences > 0);
lRet = InterlockedDecrement(&_cReferences);
if (lRet == 0)
{
delete this;
}
else if (lRet < 0)
lRet = 0;
xactDebugOut((DEB_TRACE, "Out CTransactionEnum::Release\n"));
return (ULONG)lRet;
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionEnum::Next, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 26-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CTransactionEnum::Next(ULONG celt,
ITransaction **rgelt,
ULONG *pceltFetched)
{
xactDebugOut((DEB_ITRACE, "In CTransactionEnum::Next:%p()\n", this));
ULONG cFetched = 0;
ITransaction **ptCurrent = rgelt;
for (ULONG i = 0; (_pxlCurrent != NULL) && (i < celt); i++)
{
*ptCurrent = _pxlCurrent->GetTransaction();
_pxlCurrent->GetTransaction()->AddRef();
cFetched++;
_pxlCurrent = _pxlCurrent->GetNext();
ptCurrent++;
}
if (pceltFetched != NULL)
{
*pceltFetched = cFetched;
}
xactDebugOut((DEB_ITRACE, "Out CTransactionEnum::Next\n"));
return (cFetched == celt) ? S_OK : S_FALSE;
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionEnum::Skip, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 26-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CTransactionEnum::Skip(ULONG celt)
{
xactDebugOut((DEB_ITRACE, "In CTransactionEnum::Skip:%p()\n", this));
for (ULONG i = 0; (_pxlCurrent != NULL) && (i < celt); i++)
{
_pxlCurrent = _pxlCurrent->GetNext();
}
xactDebugOut((DEB_ITRACE, "Out CTransactionEnum::Skip\n"));
return (i == celt) ? S_OK : S_FALSE;
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionEnum::Reset, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 26-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CTransactionEnum::Reset(void)
{
xactDebugOut((DEB_ITRACE, "In CTransactionEnum::Reset:%p()\n", this));
_pxlCurrent = _ptd->_pxlTransactions;
xactDebugOut((DEB_ITRACE, "Out CTransactionEnum::Reset\n"));
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Member: CTransactionEnum::Clone, public
//
// Synopsis:
//
// Arguments:
//
// Returns: Appropriate status code
//
// Modifies:
//
// History: 26-Jul-95 PhilipLa Created
//
// Notes:
//
//----------------------------------------------------------------------------
STDMETHODIMP CTransactionEnum::Clone(IEnumTransaction **ppenum)
{
SCODE sc;
xactDebugOut((DEB_ITRACE, "In CTransactionEnum::Clone:%p()\n", this));
xactMem(*ppenum = new CTransactionEnum(_ptd));
((CTransactionEnum *)(*ppenum))->_pxlCurrent = _pxlCurrent;
xactDebugOut((DEB_ITRACE, "Out CTransactionEnum::Clone\n"));
Err:
return sc;
}