//+-------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1996 - 1999 // // File: enum.cpp // // Contents: Cert Server Database interface implementation // //--------------------------------------------------------------------------- #include #pragma hdrstop #include "csprop.h" #include "row.h" #include "enum.h" #include "db.h" #include "dbw.h" #if DBG LONG g_cCertDBName; LONG g_cCertDBNameTotal; #endif CEnumCERTDBNAME::CEnumCERTDBNAME() { DBGCODE(InterlockedIncrement(&g_cCertDBName)); DBGCODE(InterlockedIncrement(&g_cCertDBNameTotal)); m_prow = NULL; m_cRef = 1; } CEnumCERTDBNAME::~CEnumCERTDBNAME() { DBGCODE(InterlockedDecrement(&g_cCertDBName)); _Cleanup(); } // CEnumCERTDBNAME implementation VOID CEnumCERTDBNAME::_Cleanup() { if (NULL != m_prow) { ((CCertDBRow *) m_prow)->EnumerateClose(m_tableid); m_prow->Release(); } } HRESULT CEnumCERTDBNAME::Open( IN ICertDBRow *prow, IN JET_TABLEID tableid, IN DWORD Flags) { HRESULT hr; if (NULL == prow) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } prow->AddRef(); m_fNoMoreData = FALSE; m_prow = prow; m_tableid = tableid; m_Flags = Flags; m_ielt = 0; m_cskip = 0; hr = S_OK; error: return(hr); } // IEnumCERTDBNAME implementation STDMETHODIMP CEnumCERTDBNAME::Next( /* [in] */ ULONG celt, /* [out] */ CERTDBNAME *rgelt, /* [out] */ ULONG *pceltFetched) { HRESULT hr; if (NULL == rgelt || NULL == pceltFetched) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } *pceltFetched = 0; if (NULL == m_prow) { hr = E_UNEXPECTED; _JumpError(hr, error, "NULL m_prow"); } if (m_fNoMoreData) { hr = S_FALSE; goto error; } CSASSERT(0 <= m_ielt); CSASSERT(0 <= m_ielt + m_cskip); DBGPRINT(( DBG_SS_CERTDBI, "Enum::Next(celt=%d) ielt=%d, skip=%d\n", celt, m_ielt, m_cskip)); hr = ((CCertDBRow *) m_prow)->EnumerateNext( &m_Flags, m_tableid, m_cskip, celt, rgelt, pceltFetched); if (S_FALSE == hr) { m_fNoMoreData = TRUE; } else { _JumpIfError(hr, error, "EnumerateNext"); } m_ielt += m_cskip; m_ielt += *pceltFetched; m_cskip = 0; error: return(hr); } STDMETHODIMP CEnumCERTDBNAME::Skip( /* [in] */ LONG celt, /* [out] */ LONG *pielt) { HRESULT hr; LONG cskipnew; if (NULL == pielt) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } if (NULL == m_prow) { hr = E_UNEXPECTED; _JumpError(hr, error, "NULL m_prow"); } cskipnew = m_cskip + celt; DBGPRINT(( DBG_SS_CERTDBI, "Enum::Skip(%d) ielt=%d: %d --> %d, skip=%d --> %d\n", celt, m_ielt, m_ielt + m_cskip, m_ielt + cskipnew, m_cskip, cskipnew)); CSASSERT(0 <= m_ielt); if (0 > cskipnew) { if (0 > m_ielt + cskipnew) { hr = E_INVALIDARG; _JumpError(hr, error, "Skip back to before start"); } m_fNoMoreData = FALSE; } *pielt = m_ielt + cskipnew; m_cskip = cskipnew; hr = S_OK; error: return(hr); } STDMETHODIMP CEnumCERTDBNAME::Reset(VOID) { HRESULT hr; LONG iDummy; hr = Skip(-(m_ielt + m_cskip), &iDummy); _JumpIfError(hr, error, "Skip"); CSASSERT(0 == iDummy); error: return(hr); } STDMETHODIMP CEnumCERTDBNAME::Clone( /* [out] */ IEnumCERTDBNAME **ppenum) { HRESULT hr; LONG iDummy; if (NULL == ppenum) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } *ppenum = NULL; if (NULL == m_prow) { hr = E_UNEXPECTED; _JumpError(hr, error, "NULL m_prow"); } hr = ((CCertDBRow *) m_prow)->EnumCertDBName( CIE_TABLE_MASK & m_Flags, ppenum); _JumpIfError(hr, error, "EnumerateCertDBName"); (*ppenum)->Skip(m_ielt + m_cskip, &iDummy); error: return(hr); } // IUnknown implementation STDMETHODIMP CEnumCERTDBNAME::QueryInterface( const IID& iid, void **ppv) { HRESULT hr; if (NULL == ppv) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } if (iid == IID_IUnknown) { *ppv = static_cast(this); } else if (iid == IID_IEnumCERTDBNAME) { *ppv = static_cast(this); } else { *ppv = NULL; hr = E_NOINTERFACE; _JumpError(hr, error, "IID"); } reinterpret_cast(*ppv)->AddRef(); hr = S_OK; error: return(hr); } ULONG STDMETHODCALLTYPE CEnumCERTDBNAME::AddRef() { return(InterlockedIncrement(&m_cRef)); } ULONG STDMETHODCALLTYPE CEnumCERTDBNAME::Release() { ULONG cRef = InterlockedDecrement(&m_cRef); if (0 == cRef) { delete this; } return(cRef); } #if 0 STDMETHODIMP CEnumCERTDBNAME::InterfaceSupportsErrorInfo( IN REFIID riid) { static const IID *arr[] = { &IID_IEnumCERTDBNAME, }; for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); i++) { if (InlineIsEqualGUID(*arr[i], riid)) { return(S_OK); } } return(S_FALSE); } #endif