742 lines
14 KiB
C++
742 lines
14 KiB
C++
|
//+--------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
||
|
//
|
||
|
// File: ext.cpp
|
||
|
//
|
||
|
// Contents: Cert Server Database interface implementation
|
||
|
//
|
||
|
//---------------------------------------------------------------------------
|
||
|
|
||
|
#include <pch.cpp>
|
||
|
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include <certdb.h>
|
||
|
#include "csdisp.h"
|
||
|
|
||
|
#include "column.h"
|
||
|
#include "attrib.h"
|
||
|
#include "ext.h"
|
||
|
#include "row.h"
|
||
|
#include "view.h"
|
||
|
|
||
|
|
||
|
#if DBG_CERTSRV
|
||
|
LONG g_cCertViewExtension;
|
||
|
LONG g_cCertViewExtensionTotal;
|
||
|
#endif
|
||
|
|
||
|
CEnumCERTVIEWEXTENSION::CEnumCERTVIEWEXTENSION()
|
||
|
{
|
||
|
DBGCODE(InterlockedIncrement(&g_cCertViewExtension));
|
||
|
DBGCODE(InterlockedIncrement(&g_cCertViewExtensionTotal));
|
||
|
m_pvw = NULL;
|
||
|
m_aelt = NULL;
|
||
|
m_cRef = 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
CEnumCERTVIEWEXTENSION::~CEnumCERTVIEWEXTENSION()
|
||
|
{
|
||
|
DBGCODE(InterlockedDecrement(&g_cCertViewExtension));
|
||
|
|
||
|
#if DBG_CERTSRV
|
||
|
if (m_cRef > 1)
|
||
|
{
|
||
|
DBGPRINT((
|
||
|
DBG_SS_CERTVIEWI,
|
||
|
"%hs has %d instances left over\n",
|
||
|
"CEnumCERTVIEWEXTENSION",
|
||
|
m_cRef));
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
if (NULL != m_aelt)
|
||
|
{
|
||
|
LocalFree(m_aelt);
|
||
|
m_aelt = NULL;
|
||
|
}
|
||
|
if (NULL != m_pvw)
|
||
|
{
|
||
|
m_pvw->Release();
|
||
|
m_pvw = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CEnumCERTVIEWEXTENSION::Open(
|
||
|
IN LONG RowId,
|
||
|
IN LONG Flags,
|
||
|
IN ICertView *pvw)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
if (NULL == pvw)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
_JumpError(hr, error, "NULL parm");
|
||
|
}
|
||
|
m_RowId = RowId;
|
||
|
m_Flags = Flags;
|
||
|
m_pvw = pvw;
|
||
|
m_pvw->AddRef();
|
||
|
|
||
|
if (0 != Flags)
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
_JumpError(hr, error, "Flags");
|
||
|
}
|
||
|
hr = Reset();
|
||
|
_JumpIfError2(hr, error, "Reset", S_FALSE);
|
||
|
|
||
|
error:
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumCERTVIEWEXTENSION::Next(
|
||
|
/* [out, retval] */ LONG *pIndex)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
DWORD celt;
|
||
|
CERTTRANSBLOB ctbExtensions;
|
||
|
|
||
|
ctbExtensions.pb = NULL;
|
||
|
if (NULL == pIndex)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
_JumpError(hr, error, "NULL parm");
|
||
|
}
|
||
|
*pIndex = -1;
|
||
|
if (m_ieltCurrent + 1 >= m_celtCurrent && !m_fNoMore)
|
||
|
{
|
||
|
hr = ((CCertView *) m_pvw)->EnumAttributesOrExtensions(
|
||
|
m_RowId,
|
||
|
CDBENUM_EXTENSIONS,
|
||
|
NULL == m_aelt?
|
||
|
NULL :
|
||
|
m_aelt[m_ieltCurrent].pwszName,
|
||
|
CEXT_CHUNK,
|
||
|
&celt,
|
||
|
&ctbExtensions);
|
||
|
if (S_FALSE == hr)
|
||
|
{
|
||
|
m_fNoMore = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_JumpIfError(hr, error, "EnumAttributesOrExtensions");
|
||
|
}
|
||
|
hr = _SaveExtensions(celt, &ctbExtensions);
|
||
|
_JumpIfError(hr, error, "_SaveExtensions");
|
||
|
|
||
|
m_ieltCurrent = -1;
|
||
|
m_celtCurrent = celt;
|
||
|
}
|
||
|
if (m_ieltCurrent + 1 >= m_celtCurrent)
|
||
|
{
|
||
|
hr = S_FALSE;
|
||
|
goto error;
|
||
|
}
|
||
|
m_ielt++;
|
||
|
m_ieltCurrent++;
|
||
|
*pIndex = m_ielt;
|
||
|
m_fNoCurrentRecord = FALSE;
|
||
|
hr = S_OK;
|
||
|
|
||
|
error:
|
||
|
if (NULL != ctbExtensions.pb)
|
||
|
{
|
||
|
CoTaskMemFree(ctbExtensions.pb);
|
||
|
}
|
||
|
return(_SetErrorInfo(hr, L"CEnumCERTVIEWEXTENSION::Next"));
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CopyMarshalledString(
|
||
|
IN CERTTRANSBLOB const *pctb,
|
||
|
IN ULONG obwsz,
|
||
|
IN BYTE *pbEnd,
|
||
|
IN BYTE **ppbNext,
|
||
|
OUT WCHAR **ppwszOut)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
*ppwszOut = NULL;
|
||
|
if (0 != obwsz)
|
||
|
{
|
||
|
WCHAR *pwsz;
|
||
|
WCHAR *pwszEnd;
|
||
|
WCHAR *pwszT;
|
||
|
DWORD cb;
|
||
|
|
||
|
pwsz = (WCHAR *) Add2Ptr(pctb->pb, obwsz);
|
||
|
pwszEnd = &((WCHAR *) pctb->pb)[pctb->cb / sizeof(WCHAR)];
|
||
|
for (pwszT = pwsz; ; pwszT++)
|
||
|
{
|
||
|
if (pwszT >= pwszEnd)
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||
|
_JumpError(hr, error, "bad marshalled data");
|
||
|
}
|
||
|
if (L'\0' == *pwszT)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
cb = (SAFE_SUBTRACT_POINTERS(pwszT, pwsz) + 1) * sizeof(WCHAR);
|
||
|
if (&(*ppbNext)[DWORDROUND(cb)] > pbEnd)
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
|
||
|
_JumpError(hr, error, "bad marshalled data");
|
||
|
}
|
||
|
CopyMemory(*ppbNext, pwsz, cb);
|
||
|
|
||
|
*ppwszOut = (WCHAR *) *ppbNext;
|
||
|
*ppbNext += DWORDROUND(cb);
|
||
|
}
|
||
|
hr = S_OK;
|
||
|
|
||
|
error:
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CopyMarshalledBlob(
|
||
|
IN CERTTRANSBLOB const *pctb,
|
||
|
IN DWORD cbValue,
|
||
|
IN ULONG obValue,
|
||
|
IN BYTE *pbEnd,
|
||
|
IN BYTE **ppbNext,
|
||
|
OUT DWORD *pcbOut,
|
||
|
OUT BYTE **ppbOut)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
*pcbOut = 0;
|
||
|
*ppbOut = NULL;
|
||
|
if (0 != obValue)
|
||
|
{
|
||
|
BYTE *pb;
|
||
|
|
||
|
pb = (BYTE *) Add2Ptr(pctb->pb, obValue);
|
||
|
if (&pb[cbValue] > &pctb->pb[pctb->cb])
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||
|
_JumpError(hr, error, "bad marshalled data");
|
||
|
}
|
||
|
if (&(*ppbNext)[DWORDROUND(cbValue)] > pbEnd)
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
|
||
|
_JumpError(hr, error, "bad marshalled data");
|
||
|
}
|
||
|
CopyMemory(*ppbNext, pb, cbValue);
|
||
|
|
||
|
*pcbOut = cbValue;
|
||
|
*ppbOut = *ppbNext;
|
||
|
*ppbNext += DWORDROUND(cbValue);
|
||
|
}
|
||
|
hr = S_OK;
|
||
|
|
||
|
error:
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CEnumCERTVIEWEXTENSION::_SaveExtensions(
|
||
|
IN DWORD celt,
|
||
|
IN CERTTRANSBLOB const *pctbExtensions)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
DWORD cbNew;
|
||
|
CERTDBEXTENSION *peltNew = NULL;
|
||
|
CERTDBEXTENSION *pelt;
|
||
|
CERTTRANSDBEXTENSION *ptelt;
|
||
|
CERTTRANSDBEXTENSION *pteltEnd;
|
||
|
BYTE *pbNext;
|
||
|
BYTE *pbEnd;
|
||
|
|
||
|
if (NULL == pctbExtensions)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
_JumpError(hr, error, "NULL parm");
|
||
|
}
|
||
|
cbNew = pctbExtensions->cb + celt * (sizeof(*pelt) - sizeof(*ptelt));
|
||
|
peltNew = (CERTDBEXTENSION *) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, cbNew);
|
||
|
if (NULL == peltNew)
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
_JumpError(hr, error, "LocalAlloc");
|
||
|
}
|
||
|
|
||
|
pteltEnd = &((CERTTRANSDBEXTENSION *) pctbExtensions->pb)[celt];
|
||
|
if ((BYTE *) pteltEnd > &pctbExtensions->pb[pctbExtensions->cb])
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||
|
_JumpError(hr, error, "bad marshalled data");
|
||
|
}
|
||
|
pelt = peltNew;
|
||
|
pbNext = (BYTE *) &peltNew[celt];
|
||
|
pbEnd = (BYTE *) Add2Ptr(peltNew, cbNew);
|
||
|
for (ptelt = (CERTTRANSDBEXTENSION *) pctbExtensions->pb;
|
||
|
ptelt < pteltEnd;
|
||
|
ptelt++, pelt++)
|
||
|
{
|
||
|
pelt->ExtFlags = ptelt->ExtFlags;
|
||
|
|
||
|
hr = CopyMarshalledString(
|
||
|
pctbExtensions,
|
||
|
ptelt->obwszName,
|
||
|
pbEnd,
|
||
|
&pbNext,
|
||
|
&pelt->pwszName);
|
||
|
_JumpIfError(hr, error, "CopyMarshalledString");
|
||
|
|
||
|
hr = CopyMarshalledBlob(
|
||
|
pctbExtensions,
|
||
|
ptelt->cbValue,
|
||
|
ptelt->obValue,
|
||
|
pbEnd,
|
||
|
&pbNext,
|
||
|
&pelt->cbValue,
|
||
|
&pelt->pbValue);
|
||
|
_JumpIfError(hr, error, "CopyMarshalledBlob");
|
||
|
}
|
||
|
CSASSERT(pbNext == pbEnd);
|
||
|
|
||
|
if (NULL != m_aelt)
|
||
|
{
|
||
|
LocalFree(m_aelt);
|
||
|
}
|
||
|
m_aelt = peltNew;
|
||
|
peltNew = NULL;
|
||
|
hr = S_OK;
|
||
|
|
||
|
error:
|
||
|
if (NULL != peltNew)
|
||
|
{
|
||
|
LocalFree(peltNew);
|
||
|
}
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CEnumCERTVIEWEXTENSION::_FindExtension(
|
||
|
OUT CERTDBEXTENSION const **ppcde)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
if (NULL == ppcde)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
_JumpError(hr, error, "NULL parm");
|
||
|
}
|
||
|
if (NULL == m_aelt)
|
||
|
{
|
||
|
hr = E_UNEXPECTED;
|
||
|
_JumpError(hr, error, "NULL m_aelt");
|
||
|
}
|
||
|
if (m_fNoCurrentRecord ||
|
||
|
m_ieltCurrent < 0 ||
|
||
|
m_ieltCurrent >= m_celtCurrent)
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
_JumpError(hr, error, "m_fNoCurrentRecord || m_ieltCurrent");
|
||
|
}
|
||
|
*ppcde = &m_aelt[m_ieltCurrent];
|
||
|
hr = S_OK;
|
||
|
|
||
|
error:
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumCERTVIEWEXTENSION::GetName(
|
||
|
/* [out, retval] */ BSTR *pstrOut)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
CERTDBEXTENSION const *pcde;
|
||
|
|
||
|
if (NULL == pstrOut)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
_JumpError(hr, error, "NULL parm");
|
||
|
}
|
||
|
hr = _FindExtension(&pcde);
|
||
|
_JumpIfError(hr, error, "_FindExtension");
|
||
|
|
||
|
if (!ConvertWszToBstr(pstrOut, pcde->pwszName, -1))
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
_JumpError(hr, error, "ConvertWszToBstr");
|
||
|
}
|
||
|
|
||
|
error:
|
||
|
return(_SetErrorInfo(hr, L"CEnumCERTVIEWEXTENSION::GetName"));
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumCERTVIEWEXTENSION::GetFlags(
|
||
|
/* [out, retval] */ LONG *pFlags)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
CERTDBEXTENSION const *pcde;
|
||
|
|
||
|
if (NULL == pFlags)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
_JumpError(hr, error, "NULL parm");
|
||
|
}
|
||
|
hr = _FindExtension(&pcde);
|
||
|
_JumpIfError(hr, error, "_FindExtension");
|
||
|
|
||
|
*pFlags = pcde->ExtFlags;
|
||
|
|
||
|
error:
|
||
|
return(_SetErrorInfo(hr, L"CEnumCERTVIEWEXTENSION::GetFlags"));
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumCERTVIEWEXTENSION::GetValue(
|
||
|
/* [in] */ LONG Type,
|
||
|
/* [in] */ LONG Flags,
|
||
|
/* [out, retval] */ VARIANT *pvarValue)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
CERTDBEXTENSION const *pcde;
|
||
|
BYTE *pballoc = NULL;
|
||
|
BYTE *pbValue;
|
||
|
DWORD cbValue;
|
||
|
|
||
|
if (NULL == pvarValue)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
_JumpError(hr, error, "NULL parm");
|
||
|
}
|
||
|
VariantInit(pvarValue);
|
||
|
pvarValue->bstrVal = NULL;
|
||
|
|
||
|
CSASSERT(CV_OUT_BASE64HEADER == CRYPT_STRING_BASE64HEADER);
|
||
|
CSASSERT(CV_OUT_BASE64 == CRYPT_STRING_BASE64);
|
||
|
CSASSERT(CV_OUT_BINARY == CRYPT_STRING_BINARY);
|
||
|
CSASSERT(CV_OUT_BASE64REQUESTHEADER == CRYPT_STRING_BASE64REQUESTHEADER);
|
||
|
CSASSERT(CV_OUT_HEX == CRYPT_STRING_HEX);
|
||
|
CSASSERT(CV_OUT_HEXADDR == CRYPT_STRING_HEXADDR);
|
||
|
CSASSERT(CV_OUT_BASE64X509CRLHEADER == CRYPT_STRING_BASE64X509CRLHEADER);
|
||
|
CSASSERT(CV_OUT_HEXASCII == CRYPT_STRING_HEXASCII);
|
||
|
CSASSERT(CV_OUT_HEXASCIIADDR == CRYPT_STRING_HEXASCIIADDR);
|
||
|
|
||
|
switch (Flags)
|
||
|
{
|
||
|
case CV_OUT_BASE64HEADER:
|
||
|
case CV_OUT_BASE64:
|
||
|
case CV_OUT_BINARY:
|
||
|
case CV_OUT_BASE64REQUESTHEADER:
|
||
|
case CV_OUT_HEX:
|
||
|
case CV_OUT_HEXASCII:
|
||
|
case CV_OUT_BASE64X509CRLHEADER:
|
||
|
case CV_OUT_HEXADDR:
|
||
|
case CV_OUT_HEXASCIIADDR:
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
hr = E_INVALIDARG;
|
||
|
_JumpError(hr, error, "Flags");
|
||
|
}
|
||
|
|
||
|
|
||
|
hr = _FindExtension(&pcde);
|
||
|
_JumpIfError(hr, error, "_FindExtension");
|
||
|
|
||
|
if (0 == pcde->cbValue || NULL == pcde->pbValue)
|
||
|
{
|
||
|
hr = CERTSRV_E_PROPERTY_EMPTY;
|
||
|
_JumpError(hr, error, "NULL value");
|
||
|
}
|
||
|
if (PROPTYPE_BINARY == (PROPTYPE_MASK & Type))
|
||
|
{
|
||
|
pbValue = pcde->pbValue;
|
||
|
cbValue = pcde->cbValue;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = myDecodeExtension(
|
||
|
Type,
|
||
|
pcde->pbValue,
|
||
|
pcde->cbValue,
|
||
|
&pballoc,
|
||
|
&cbValue);
|
||
|
_JumpIfError(hr, error, "myDecodeExtension");
|
||
|
|
||
|
pbValue = pballoc;
|
||
|
}
|
||
|
if (CV_OUT_BINARY == Flags)
|
||
|
{
|
||
|
switch (PROPTYPE_MASK & Type)
|
||
|
{
|
||
|
case PROPTYPE_LONG:
|
||
|
CSASSERT(sizeof(LONG) == cbValue);
|
||
|
pvarValue->lVal = *(LONG *) pbValue;
|
||
|
pvarValue->vt = VT_I4;
|
||
|
break;
|
||
|
|
||
|
case PROPTYPE_DATE:
|
||
|
CSASSERT(sizeof(FILETIME) == cbValue);
|
||
|
|
||
|
hr = myFileTimeToDate(
|
||
|
(FILETIME const *) pbValue,
|
||
|
&pvarValue->date);
|
||
|
_JumpIfError(hr, error, "myFileTimeToDate");
|
||
|
|
||
|
pvarValue->vt = VT_DATE;
|
||
|
break;
|
||
|
|
||
|
case PROPTYPE_STRING:
|
||
|
case PROPTYPE_BINARY:
|
||
|
if (!ConvertWszToBstr(
|
||
|
&pvarValue->bstrVal,
|
||
|
(WCHAR const *) pbValue,
|
||
|
cbValue))
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
_JumpError(hr, error, "ConvertWszToBstr");
|
||
|
}
|
||
|
pvarValue->vt = VT_BSTR;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
hr = E_INVALIDARG;
|
||
|
_JumpError(hr, error, "Type");
|
||
|
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = EncodeCertString(
|
||
|
pbValue,
|
||
|
cbValue,
|
||
|
Flags,
|
||
|
&pvarValue->bstrVal);
|
||
|
_JumpIfError(hr, error, "EncodeCertString");
|
||
|
|
||
|
pvarValue->vt = VT_BSTR;
|
||
|
}
|
||
|
|
||
|
error:
|
||
|
if (NULL != pballoc)
|
||
|
{
|
||
|
LocalFree(pballoc);
|
||
|
}
|
||
|
return(_SetErrorInfo(hr, L"CEnumCERTVIEWEXTENSION::GetValue"));
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumCERTVIEWEXTENSION::Skip(
|
||
|
/* [in] */ LONG celt)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
LONG ieltnew = m_ielt + celt;
|
||
|
|
||
|
if (-1 > ieltnew)
|
||
|
{
|
||
|
hr = E_INVALIDARG;
|
||
|
_JumpError(hr, error, "Skip back to before start");
|
||
|
}
|
||
|
m_ielt = ieltnew;
|
||
|
m_ieltCurrent += celt;
|
||
|
m_fNoCurrentRecord = TRUE;
|
||
|
hr = S_OK;
|
||
|
|
||
|
error:
|
||
|
return(_SetErrorInfo(hr, L"CEnumCERTVIEWEXTENSION::Skip"));
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumCERTVIEWEXTENSION::Reset(VOID)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
DWORD celt;
|
||
|
CERTTRANSBLOB ctbExtensions;
|
||
|
|
||
|
ctbExtensions.pb = NULL;
|
||
|
m_fNoMore = FALSE;
|
||
|
|
||
|
hr = ((CCertView *) m_pvw)->EnumAttributesOrExtensions(
|
||
|
m_RowId,
|
||
|
CDBENUM_EXTENSIONS,
|
||
|
NULL,
|
||
|
CEXT_CHUNK,
|
||
|
&celt,
|
||
|
&ctbExtensions);
|
||
|
if (S_FALSE == hr)
|
||
|
{
|
||
|
m_fNoMore = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
_JumpIfError(hr, error, "EnumAttributesOrExtensions");
|
||
|
}
|
||
|
|
||
|
hr = _SaveExtensions(celt, &ctbExtensions);
|
||
|
_JumpIfError(hr, error, "_SaveExtensions");
|
||
|
|
||
|
m_ielt = -1;
|
||
|
m_ieltCurrent = -1;
|
||
|
m_celtCurrent = celt;
|
||
|
m_fNoCurrentRecord = TRUE;
|
||
|
|
||
|
error:
|
||
|
if (NULL != ctbExtensions.pb)
|
||
|
{
|
||
|
CoTaskMemFree(ctbExtensions.pb);
|
||
|
}
|
||
|
return(_SetErrorInfo(hr, L"CEnumCERTVIEWEXTENSION::Reset"));
|
||
|
}
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CEnumCERTVIEWEXTENSION::Clone(
|
||
|
/* [out] */ IEnumCERTVIEWEXTENSION **ppenum)
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
IEnumCERTVIEWEXTENSION *penum = NULL;
|
||
|
|
||
|
if (NULL == ppenum)
|
||
|
{
|
||
|
hr = E_POINTER;
|
||
|
_JumpError(hr, error, "NULL parm");
|
||
|
}
|
||
|
*ppenum = NULL;
|
||
|
|
||
|
penum = new CEnumCERTVIEWEXTENSION;
|
||
|
if (NULL == penum)
|
||
|
{
|
||
|
hr = E_OUTOFMEMORY;
|
||
|
_JumpError(hr, error, "new CEnumCERTVIEWEXTENSION");
|
||
|
}
|
||
|
|
||
|
hr = ((CEnumCERTVIEWEXTENSION *) penum)->Open(m_RowId, m_Flags, m_pvw);
|
||
|
_JumpIfError(hr, error, "Open");
|
||
|
|
||
|
if (-1 != m_ielt)
|
||
|
{
|
||
|
hr = penum->Skip(m_ielt);
|
||
|
_JumpIfError(hr, error, "Skip");
|
||
|
|
||
|
if (!m_fNoCurrentRecord)
|
||
|
{
|
||
|
LONG Index;
|
||
|
|
||
|
hr = penum->Next(&Index);
|
||
|
_JumpIfError(hr, error, "Next");
|
||
|
|
||
|
CSASSERT(Index == m_ielt);
|
||
|
}
|
||
|
}
|
||
|
*ppenum = penum;
|
||
|
penum = NULL;
|
||
|
hr = S_OK;
|
||
|
|
||
|
error:
|
||
|
if (NULL != penum)
|
||
|
{
|
||
|
penum->Release();
|
||
|
}
|
||
|
return(_SetErrorInfo(hr, L"CEnumCERTVIEWEXTENSION::Clone"));
|
||
|
}
|
||
|
|
||
|
|
||
|
HRESULT
|
||
|
CEnumCERTVIEWEXTENSION::_SetErrorInfo(
|
||
|
IN HRESULT hrError,
|
||
|
IN WCHAR const *pwszDescription)
|
||
|
{
|
||
|
CSASSERT(FAILED(hrError) || S_OK == hrError || S_FALSE == hrError);
|
||
|
if (FAILED(hrError))
|
||
|
{
|
||
|
HRESULT hr;
|
||
|
|
||
|
hr = DispatchSetErrorInfo(
|
||
|
hrError,
|
||
|
pwszDescription,
|
||
|
wszCLASS_CERTVIEW L".CEnumCERTVIEWEXTENSION",
|
||
|
&IID_IEnumCERTVIEWEXTENSION);
|
||
|
CSASSERT(hr == hrError);
|
||
|
}
|
||
|
return(hrError);
|
||
|
}
|
||
|
|
||
|
|
||
|
#if 1
|
||
|
// IUnknown implementation
|
||
|
STDMETHODIMP
|
||
|
CEnumCERTVIEWEXTENSION::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<IEnumCERTVIEWEXTENSION *>(this);
|
||
|
}
|
||
|
else if (iid == IID_IDispatch)
|
||
|
{
|
||
|
*ppv = static_cast<IEnumCERTVIEWEXTENSION *>(this);
|
||
|
}
|
||
|
else if (iid == IID_IEnumCERTVIEWEXTENSION)
|
||
|
{
|
||
|
*ppv = static_cast<IEnumCERTVIEWEXTENSION *>(this);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*ppv = NULL;
|
||
|
hr = E_NOINTERFACE;
|
||
|
_JumpError(hr, error, "IID");
|
||
|
}
|
||
|
reinterpret_cast<IUnknown *>(*ppv)->AddRef();
|
||
|
hr = S_OK;
|
||
|
|
||
|
error:
|
||
|
return(hr);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG STDMETHODCALLTYPE
|
||
|
CEnumCERTVIEWEXTENSION::AddRef()
|
||
|
{
|
||
|
return(InterlockedIncrement(&m_cRef));
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG STDMETHODCALLTYPE
|
||
|
CEnumCERTVIEWEXTENSION::Release()
|
||
|
{
|
||
|
ULONG cRef = InterlockedDecrement(&m_cRef);
|
||
|
|
||
|
if (0 == cRef)
|
||
|
{
|
||
|
delete this;
|
||
|
}
|
||
|
return(cRef);
|
||
|
}
|
||
|
#endif
|