windows-nt/Source/XPSP1/NT/ds/adsi/router/cenumacl.cxx
2020-09-26 16:20:57 +08:00

459 lines
9.2 KiB
C++

//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996
//
// File: cenumacl.cxx
//
// Contents: Access Control List Enumerator Code
//
// CAccCtrlListEnum::Create
// CAccCtrlListEnum::CAccCtrlListEnum
// CAccCtrlListEnum::~CAccCtrlListEnum
// CAccCtrlListEnum::QueryInterface
// CAccCtrlListEnum::AddRef
// CAccCtrlListEnum::Release
// CAccCtrlListEnum::Next
// CAccCtrlListEnum::Skip
// CAccCtrlListEnum::Clone
//
// History: 03-26-98 AjayR Created.
// This file was cloned from ldap\cenumvar.cxx
//----------------------------------------------------------------------------
#include "procs.hxx"
#pragma hdrstop
#include "oleds.hxx"
//+---------------------------------------------------------------------------
//
// Function: CAccCtrlListEnum::CAccCtrlListEnum
//
// Synopsis:
//
//
// Arguments:
//
//
// Returns:
//
// Modifies:
//
// History: 03-26-96 AjayR Cloned from ldap\cenumvar.
//
//----------------------------------------------------------------------------
CAccCtrlListEnum::CAccCtrlListEnum()
{
//
// Set the reference count on the enumerator.
//
_cRef = 1;
_pACL = NULL;
_curElement = 0;
}
//+---------------------------------------------------------------------------
//
// Function: CAccCtrlListEnum::~CAccCtrlListEnum
//
// Synopsis:
//
//
// Arguments:
//
// Returns:
//
// Modifies:
//
// History: 01-30-95 krishnag Created.
//
//----------------------------------------------------------------------------
CAccCtrlListEnum::~CAccCtrlListEnum()
{
//
// Bump down the reference count on the Collection object
//
//
// Remove its entry (in ACL) as an enumerator of the ACL
//
if (_pACL) {
_pACL->RemoveEnumerator(this);
}
// Release the ACL if we have a ref on it
if (_pACL) {
_pACL->Release();
_pACL = NULL;
}
}
//+---------------------------------------------------------------------------
//
// Function: CAccCtrlListEnum::QueryInterface
//
// Synopsis:
//
// Arguments: [iid]
// [ppv]
//
// Returns: HRESULT
//
// Modifies:
//
// History: 01-30-95 krishnag Created.
//
//----------------------------------------------------------------------------
STDMETHODIMP
CAccCtrlListEnum::QueryInterface(
REFIID iid,
void FAR* FAR* ppv
)
{
if (ppv == NULL) {
RRETURN(E_POINTER);
}
*ppv = NULL;
if (iid == IID_IUnknown || iid == IID_IEnumVARIANT) {
*ppv = this;
}
else {
return ResultFromScode(E_NOINTERFACE);
}
AddRef();
return NOERROR;
}
//+---------------------------------------------------------------------------
//
// Function: CAccCtrlListEnum::AddRef
//
// Synopsis:
//
// Arguments:
//
// Returns: HRESULT
//
// Modifies:
//
// History: 01-30-95 krishnag Created.
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG)
CAccCtrlListEnum::AddRef(void)
{
return ++_cRef;
}
//+---------------------------------------------------------------------------
//
// Function: CAccCtrlListEnum::Release
//
// Synopsis:
//
//
// Arguments: [void]
//
// Returns:
//
// Modifies:
//
// History: 01-30-95 krishnag Created.
//----------------------------------------------------------------------------
STDMETHODIMP_(ULONG)
CAccCtrlListEnum::Release(void)
{
if(--_cRef == 0){
delete this;
return 0;
}
return _cRef;
}
//+---------------------------------------------------------------------------
//
// Function: CAccCtrlListEnum::Skip
//
// Synopsis:
//
// Arguments: [cElements]
//
// Returns: HRESULT
//
// Modifies:
//
// History: 01-30-95 krishnag Created.
//
//----------------------------------------------------------------------------
STDMETHODIMP
CAccCtrlListEnum::Skip(ULONG cElements)
{
RRETURN(E_NOTIMPL);
}
//+---------------------------------------------------------------------------
//
// Function: CAccCtrlListEnum::Reset
//
// Synopsis:
//
// Arguments: []
//
// Returns: HRESULT
//
// Modifies:
//
// History:
//
//----------------------------------------------------------------------------
STDMETHODIMP
CAccCtrlListEnum::Reset()
{
RRETURN(E_NOTIMPL);
}
//+---------------------------------------------------------------------------
//
// Function: CAccCtrlListEnum::Clone
//
// Synopsis:
//
// Arguments: [pCollection]
// [ppEnum]
//
// Returns: HRESULT
//
// Modifies:
//
// History: 01-30-95 krishnag Created.
//
//----------------------------------------------------------------------------
STDMETHODIMP
CAccCtrlListEnum::Clone(IEnumVARIANT FAR* FAR* ppenum)
{
RRETURN(E_NOTIMPL);
}
//+---------------------------------------------------------------------------
//
// Function: CAccCtrlListEnum::Create
//
// Synopsis: Create the enumeration object and initialise the
// the member variables with the appropritate values.
//
// Arguments: [ppEnumVariant]
// [pACL] Pointer to CAccessControlList
//
// Returns: HRESULT
//
// Modifies: [ppEnumVariant]
//
//----------------------------------------------------------------------------
HRESULT
CAccCtrlListEnum::CreateAclEnum(
CAccCtrlListEnum FAR* FAR* ppEnumVariant,
CAccessControlList *pACL
)
{
HRESULT hr = S_OK;
CAccCtrlListEnum FAR* pEnumVariant = NULL;
*ppEnumVariant = NULL;
pEnumVariant = new CAccCtrlListEnum();
if (!pEnumVariant) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
// Note that we need to release this when we get rid of this object
pACL->AddRef();
pEnumVariant->_pACL = pACL;
error:
if (FAILED(hr))
delete pEnumVariant;
else
*ppEnumVariant = pEnumVariant;
RRETURN_EXP_IF_ERR(hr);
}
// This method only returns one element at a time even if more
// than one element is asked for, of course pcElmentFetched is
// returned as one.
STDMETHODIMP
CAccCtrlListEnum::Next(
ULONG cElements,
VARIANT FAR* pvar,
ULONG FAR* pcElementFetched
)
{
HRESULT hr = S_FALSE;
DWORD dwAceCount = 0;
IADsAccessControlEntry *pAce = NULL;
IDispatch *pDispatch = NULL;
PVARIANT pThisVar = pvar;
if (pcElementFetched) {
*pcElementFetched = 0;
}
if (_pACL == NULL) {
RRETURN(hr = S_FALSE);
}
// Will get the ace count each time so that changes in the
// ACL do not affect the enum object
//
// ** Changes in ACL does affect the enum object. We should still get
// AceCount and check if _curElement within bounds as defensive
// programming - especially since current model does not add critical
// section protection on the enumerator for multi-threaded model.
//
hr = _pACL->get_AceCount((long *)&dwAceCount);
BAIL_ON_FAILURE(hr);
if (dwAceCount == 0) {
hr = S_FALSE;
RRETURN(hr);
}
//
// valid dwAceCount here (See **)
//
if (_curElement < dwAceCount) {
// bump up the curElement as we start at 0
_curElement++;
// get the corresponding acl pointer and QI it
hr = _pACL->GetElement(_curElement, &pAce);
BAIL_ON_FAILURE(hr);
if (hr != S_FALSE) {
hr = pAce->QueryInterface(
IID_IDispatch,
(void **)&pDispatch
);
BAIL_ON_FAILURE(hr);
V_DISPATCH(pThisVar) = pDispatch;
V_VT(pThisVar) = VT_DISPATCH;
if (pcElementFetched) {
*pcElementFetched = 1;
}
} else {
RRETURN_EXP_IF_ERR(hr);
}
} else {
// In this case, we need to set hr to S_FALSE
// as we have returned all the aces.
hr = S_FALSE;
}
RRETURN(hr);
error:
// if the disp pointer is valid then need to release on ACE
if (pDispatch) {
pAce->Release();
}
RRETURN(hr);
}
BOOL
CAccCtrlListEnum::
DecrementCurElement(
)
{
if (_pACL && _curElement>=1) {
_curElement--;
return TRUE;
} else { // !pACL || _curElement ==0
//
// do not decrement _curElement since lower bound limit on curElement
// is 0.
//
return FALSE;
}
}
BOOL
CAccCtrlListEnum::
IncrementCurElement(
)
{
HRESULT hr = E_FAIL;
DWORD dwAceCount;
if (!_pACL)
return FALSE;
hr = _pACL->get_AceCount((long *)&dwAceCount);
if (FAILED(hr)) {
return FALSE;
}
if (_curElement>=dwAceCount-1) {
//
// do not increment _curElement since upper bound limit on curElement
// already reached; upperbound limit is actually dwAceCount-1 since
// Next() increment _curElement by 1 before calling
// GetElement(_curElement). See Next() for details.
//
return FALSE;
}
_curElement++;
return TRUE;
}
DWORD
CAccCtrlListEnum::
GetCurElement(
)
{
return _curElement;
}