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