/*****************************************************************************\ * MODULE: enum.cpp * * PURPOSE: Implementation of COM interface for BidiSpooler * * Copyright (C) 2000 Microsoft Corporation * * History: * * 03/09/00 Weihai Chen (weihaic) Created * \*****************************************************************************/ #include "precomp.h" #include "priv.h" TBidiRequestContainerEnum::TBidiRequestContainerEnum ( TBidiRequestContainer & refContainer, TReqInterfaceList & refReqList): m_refReqList (refReqList), m_refContainer (refContainer), m_cRef (1) { m_refContainer.AddRef (); TAutoCriticalSection CritSec (m_refReqList); if (CritSec.bValid ()) { m_pHead = m_refReqList.GetHead(); m_pCurrent = m_pHead; m_bValid = TRUE; } else m_bValid = FALSE; } TBidiRequestContainerEnum::TBidiRequestContainerEnum ( TBidiRequestContainerEnum & refEnum): m_refReqList (refEnum.m_refReqList), m_refContainer (refEnum.m_refContainer), m_cRef (1) { m_refContainer.AddRef (); TAutoCriticalSection CritSec (m_refReqList); if (CritSec.bValid ()) { m_pHead = refEnum.m_pHead; m_pCurrent = refEnum.m_pCurrent; m_bValid = TRUE; } else m_bValid = FALSE; } TBidiRequestContainerEnum::~TBidiRequestContainerEnum () { DBGMSG(DBG_TRACE,("TBidiRequestContainerEnum Destory Self\n")); m_refContainer.Release (); } STDMETHODIMP TBidiRequestContainerEnum::QueryInterface ( REFIID iid, void** ppv) { HRESULT hr = S_OK; DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum QI\n")); if (iid == IID_IUnknown) { *ppv = static_cast(this) ; } else if (iid == IID_IEnumUnknown) { *ppv = static_cast(this) ; } else { *ppv = NULL ; hr = E_NOINTERFACE ; } if (*ppv) { reinterpret_cast(*ppv)->AddRef() ; } DBGMSG(DBG_TRACE,("Leave TBidiRequestContainerEnum QI hr=%x\n", hr)); return hr ; } STDMETHODIMP_ (ULONG) TBidiRequestContainerEnum::AddRef () { DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum::AddRef ref= %d\n", m_cRef)); // We add a reference to the container so that the container won't // delete the list where there is an outstadning enummeration // return InterlockedIncrement(&m_cRef) ; } STDMETHODIMP_ (ULONG) TBidiRequestContainerEnum::Release () { DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum::Release ref= %d\n", m_cRef)); if (InterlockedDecrement(&m_cRef) == 0) { delete this ; return 0 ; } return m_cRef ; } STDMETHODIMP TBidiRequestContainerEnum::Next ( IN ULONG celt, OUT IUnknown ** rgelt, OUT ULONG * pceltFetched) { HRESULT hr; DWORD dwCount = 0; DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum::Next\n")); if (m_bValid) { if (rgelt && pceltFetched) { TAutoCriticalSection CritSec (m_refReqList); if (CritSec.bValid ()) { while (m_pCurrent && dwCount < celt) { TBidiRequestInterfaceData * pData = m_pCurrent->GetData (); *rgelt = (IUnknown *) pData->GetInterface(); (*rgelt++)->AddRef (); m_pCurrent = m_pCurrent->GetNext (); dwCount++; } *pceltFetched = dwCount; hr = S_OK; } else hr = LastError2HRESULT (); } else hr = E_POINTER; } else hr = E_HANDLE; return hr; } STDMETHODIMP TBidiRequestContainerEnum::Skip ( IN ULONG celt) { HRESULT hr; DWORD dwCount = 0; DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum::Skip\n")); if (m_bValid) { TAutoCriticalSection CritSec (m_refReqList); if (CritSec.bValid ()) { while (m_pCurrent && dwCount < celt) { m_pCurrent = m_pCurrent->GetNext (); dwCount++; } hr = S_OK; } else hr = LastError2HRESULT (); } else hr = E_HANDLE; return hr; } STDMETHODIMP TBidiRequestContainerEnum::Reset(void) { DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum::Reset\n")); if (m_bValid) { m_pCurrent = m_pHead; return S_OK; } else return E_HANDLE; } STDMETHODIMP TBidiRequestContainerEnum::Clone( OUT IEnumUnknown ** ppenum) { HRESULT hr; DBGMSG(DBG_TRACE,("Enter TBidiRequestContainerEnum::Clone\n")); if (m_bValid) { hr = PrivCreateComponent ( new TBidiRequestContainerEnum (*this), IID_IEnumUnknown, (void **)ppenum); } else hr = E_HANDLE; return hr; }