windows-nt/Source/XPSP1/NT/ds/security/services/ca/certdb/enum.cpp

315 lines
5 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: enum.cpp
//
// Contents: Cert Server Database interface implementation
//
//---------------------------------------------------------------------------
#include <pch.cpp>
#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<IEnumCERTDBNAME *>(this);
}
else if (iid == IID_IEnumCERTDBNAME)
{
*ppv = static_cast<IEnumCERTDBNAME *>(this);
}
else
{
*ppv = NULL;
hr = E_NOINTERFACE;
_JumpError(hr, error, "IID");
}
reinterpret_cast<IUnknown *>(*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