CENUMNS.CPP

/*++ 

Copyright (c) 1996 Microsoft Corporation

Module Name:

CEnumNS.c

Abstract:

Sample Provider Namespace Enumerator Code

Author:

Environment:

User mode

Revision History :

--*/
#include "adssmp.h"
#pragma hdrstop

#define ENUM_BUFFER_SIZE (1024 * 16)

//+---------------------------------------------------------------------------
//
// Function: CSampleDSNamespaceEnum::Create
//
// Synopsis:
//
// Arguments: [pCollection]
// [ppEnumVariant]
//
// Returns: HRESULT
//
// Modifies:
//
//----------------------------------------------------------------------------
HRESULT
CSampleDSNamespaceEnum::Create(
CSampleDSNamespaceEnum FAR* FAR* ppenumvariant,
VARIANT var
)
{
HRESULT hr = S_OK;
CSampleDSNamespaceEnum FAR* penumvariant = NULL;

penumvariant = new CSampleDSNamespaceEnum();

if (penumvariant == NULL){
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}

hr = SampleDSRDNEnum(
&penumvariant->_hEnum,
NULL
);
BAIL_ON_FAILURE(hr);

hr = ObjectTypeList::CreateObjectTypeList(
var,
&penumvariant->_pObjList
);
BAIL_ON_FAILURE(hr);

*ppenumvariant = penumvariant;
RRETURN(hr);

error:
if (penumvariant) {
delete penumvariant;
}
RRETURN(hr);
}

//+---------------------------------------------------------------------------
//
// Function: CSampleDSNamespaceEnum::CSampleDSNamespaceEnum
//
// Synopsis:
//
//
// Arguments:
//
//
// Returns:
//
//----------------------------------------------------------------------------
CSampleDSNamespaceEnum::CSampleDSNamespaceEnum()
{
_pObjList = NULL;
_dwEntriesRead = 0;
_dwCurrentEntry = 0;
_hEnum = NULL;
_pBuffer = NULL;
}

//+---------------------------------------------------------------------------
//
// Function: CSampleDSNamespaceEnum::~CSampleDSNamespaceEnum
//
// Synopsis:
//
//
// Arguments:
//
// Returns:
//
//----------------------------------------------------------------------------
CSampleDSNamespaceEnum::~CSampleDSNamespaceEnum()
{
if (_pBuffer)
FreeProvMem(_pBuffer);
}

//+---------------------------------------------------------------------------
//
// Function: CSampleDSNamespaceEnum::Next
//
// Synopsis: Returns cElements number of requested ADs objects in the
// array supplied in pvar.
//
// Arguments: [cElements] -- The number of elements requested by client
// [pvar] -- ptr to array of VARIANTs to for return objects
// [pcElementFetched] -- if non-NULL, then number of elements
// -- actually returned is placed here
//
// Returns: HRESULT -- S_OK if number of elements requested are returned
// -- S_FALSE if number of elements is < requested
//
//----------------------------------------------------------------------------
STDMETHODIMP
CSampleDSNamespaceEnum::Next(
ULONG cElements,
VARIANT FAR* pvar,
ULONG FAR* pcElementFetched
)
{
ULONG cElementFetched = 0;
HRESULT hr = S_OK;

hr = EnumObjects(
cElements,
pvar,
&cElementFetched
);

if (pcElementFetched) {
*pcElementFetched = cElementFetched;
}
RRETURN(hr);
}


HRESULT
CSampleDSNamespaceEnum::EnumObjects(
ULONG cElements,
VARIANT FAR* pvar,
ULONG FAR* pcElementFetched
)
{
DWORD i;
ULONG cRequested = 0;
ULONG cTotalFetched = 0;
HRESULT hr;

for (i = 0; i < cElements; i++) {
VariantInit(&pvar[i]);
}
cRequested = cElements;

hr = FetchObjects(cElements, pvar, &cTotalFetched);

if (pcElementFetched) {
*pcElementFetched = cTotalFetched;
}

RRETURN(hr);
}

//
// Load IDispatch pointers of Next cElements Root Objects into pvar array
//
HRESULT
CSampleDSNamespaceEnum::FetchObjects(

ULONG cElements,
VARIANT FAR* pvar,
ULONG FAR* pcElementFetched
)
{
HRESULT hr;
IDispatch *pDispatch = NULL;
DWORD i = 0;

while (i < cElements) {

hr = FetchNextObject(&pDispatch);
if (hr == S_FALSE) {
break;
}

VariantInit(&pvar[i]);
pvar[i].vt = VT_DISPATCH;
pvar[i].pdispVal = pDispatch;
(*pcElementFetched)++;
i++;
}
return(hr);
}


//+---------------------------------------------------------------------------
//
// Function: CSampleDSNamespaceEnum::FetchNextObject
//
// Synopsis: Gets IDispatch pointer of next object in namespace.
//
// Arguments: [ppDispatch] -- Pointer to where to return IDispatch pointer.
//
// Returns: HRESULT -- S_OK if got the next object
// -- S_FALSE if not
//
// Modifies: [*ppDispatch]
//
//----------------------------------------------------------------------------
HRESULT
CSampleDSNamespaceEnum::FetchNextObject(
IDispatch ** ppDispatch
)
{
HRESULT hr;
LPTSTR lpRootRDN=NULL ;
LPTSTR lpClassName=NULL ;
*ppDispatch = NULL;

hr = SampleDSNextRDN(_hEnum,
&lpRootRDN,
&lpClassName
);

if (hr != S_OK) {
if (_hEnum) {
SampleDSFreeEnum(_hEnum);
_hEnum = NULL;
}
goto error;
}

hr = CSampleDSGenObject::CreateGenericObject(
L"Sample:",
lpRootRDN,
lpClassName,
ADS_OBJECT_BOUND,
IID_IDispatch,
(void **)ppDispatch
);
error:
if (lpClassName)
FreeProvMem(lpClassName);
if (lpRootRDN)
FreeProvMem(lpRootRDN);
RRETURN_ENUM_STATUS(hr);
}