CENUMSCH.CPP

/*++ 

Copyright (c) 1996 Microsoft Corporation

Module Name:

CEnumSch.cpp

Abstract:

Sample Provider Enum Schema functionality

Author:

Environment:

User mode

Revision History :

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

//+---------------------------------------------------------------------------
//
// Function: CSampleDSSchemaEnum::Create
//
// Synopsis:
//
// Arguments: [pCollection]
// [ppEnumVariant]
//
// Returns: HRESULT
//
// Modifies:
//
// History: 01-30-95 yihsins Created.
//
//----------------------------------------------------------------------------
HRESULT
CSampleDSSchemaEnum::Create(
CSampleDSSchemaEnum FAR* FAR* ppenumvariant,
BSTR bstrSampleDSTreeName,
BSTR bstrADsPath,
BSTR bstrName,
VARIANT var
)
{
HRESULT hr = S_OK;
CSampleDSSchemaEnum FAR* penumvariant = NULL;

*ppenumvariant = NULL;

penumvariant = new CSampleDSSchemaEnum();
if (!penumvariant)
{
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}

hr = ProvAllocString( bstrSampleDSTreeName, &penumvariant->_bstrSampleDSTreeName);
BAIL_ON_FAILURE(hr);
hr = ProvAllocString( bstrADsPath, &penumvariant->_bstrADsPath);
BAIL_ON_FAILURE(hr);

hr = ProvAllocString( bstrName, &penumvariant->_bstrName);
BAIL_ON_FAILURE(hr);

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

*ppenumvariant = penumvariant;

RRETURN(hr);

error:

delete penumvariant;

RRETURN(hr);
}

CSampleDSSchemaEnum::CSampleDSSchemaEnum()
: _bstrADsPath( NULL ),
_bstrName( NULL ),
_bstrSampleDSTreeName( NULL ),
_pObjList( NULL )
{
_lpClassDefs = NULL;
_dwClassCurrent = 0;
_dwClassReturned = 0;

_lpAttrDefs = NULL;
_dwAttrCurrent = 0;
_dwAttrReturned = 0;

}

CSampleDSSchemaEnum::~CSampleDSSchemaEnum()
{
ProvFreeString( _bstrName );
ProvFreeString( _bstrADsPath );
ProvFreeString( _bstrSampleDSTreeName );


if ( _pObjList != NULL )
{
delete _pObjList;
_pObjList = NULL;
}
}

//+---------------------------------------------------------------------------
//
// Function: CSampleDSSchemaEnum::Next
//
// Synopsis: Returns cElements number of requested NetOle 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
//
// Modifies:
//
// History: 11-3-95 yihsins Created.
//
//----------------------------------------------------------------------------
STDMETHODIMP
CSampleDSSchemaEnum::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
CSampleDSSchemaEnum::EnumObjects(
DWORD ObjectType,
ULONG cElements,
VARIANT FAR * pvar,
ULONG FAR * pcElementFetched
)
{
switch (ObjectType)
{
case SampleDS_CLASS_ID:
RRETURN (EnumClasses(cElements, pvar, pcElementFetched));

case SampleDS_PROPERTY_ID:
RRETURN (EnumProperties(cElements, pvar, pcElementFetched));

default:
RRETURN(S_FALSE);
}
}

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

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

cRequested = cElements;

while ( SUCCEEDED( _pObjList->GetCurrentObject(&ObjectType))
&& ((hr = EnumObjects( ObjectType,
cRequested,
pPathvar,
&cFetchedByPath)) == S_FALSE )
)
{
pPathvar += cFetchedByPath;
cRequested -= cFetchedByPath;
cTotalFetched += cFetchedByPath;

cFetchedByPath = 0;

if ( FAILED(_pObjList->Next()) )
{
if ( pcElementFetched )
*pcElementFetched = cTotalFetched;
RRETURN(S_FALSE);
}
}

if ( pcElementFetched )
*pcElementFetched = cTotalFetched + cFetchedByPath;

RRETURN(hr);
}

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

while ( i < cElements )
{
hr = GetClassObject(&pDispatch);
if ( hr == S_FALSE )
break;

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

RRETURN(hr);
}

HRESULT
CSampleDSSchemaEnum::GetClassObject(
IDispatch ** ppDispatch
)
{
HRESULT hr = S_OK;
LPSampleDS_CLASS_DEF lpCurrentObject = NULL;

if (!_lpClassDefs) {
_dwClassCurrent = 0;
hr = SampleDSGetClassDefinition(&_lpClassDefs,
&_dwClassReturned);
BAIL_ON_FAILURE(hr);
}

if (_dwClassCurrent == _dwClassReturned) {
goto error;
}

if (_dwClassCurrent < _dwClassReturned) {

//
// Now send back the current object
//

lpCurrentObject = _lpClassDefs + _dwClassCurrent;


hr = CSampleDSClass::CreateClass(
_bstrADsPath,
lpCurrentObject->lpClassName,
lpCurrentObject,
ADS_OBJECT_BOUND,
IID_IDispatch,
(void **)ppDispatch
);
BAIL_ON_FAILURE(hr);
_dwClassCurrent++;

RRETURN(S_OK);

}

error:
if (_lpClassDefs) {
SampleDSFreeClassDefinition(_lpClassDefs,
_dwClassReturned);
}
*ppDispatch = NULL;
RRETURN(S_FALSE);
}

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

while ( i < cElements )
{
hr = GetPropertyObject(&pDispatch);
if ( hr == S_FALSE )
break;

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

RRETURN(hr);
}

HRESULT
CSampleDSSchemaEnum::GetPropertyObject(
IDispatch ** ppDispatch
)
{
HRESULT hr = S_OK;

LPSampleDS_ATTR_DEF lpCurrentObject = NULL;

if (!_lpAttrDefs) {
_dwAttrCurrent = 0;
hr = SampleDSGetPropertyDefinition(&_lpAttrDefs,
&_dwAttrReturned);
BAIL_ON_FAILURE(hr);
}

if (_dwAttrCurrent == _dwAttrReturned) {
goto error;
}

if (_dwAttrCurrent < _dwAttrReturned) {

lpCurrentObject = _lpAttrDefs + _dwAttrCurrent;

hr = CSampleDSProperty::CreateProperty(
_bstrADsPath,
lpCurrentObject->lpAttributeName,
lpCurrentObject,
ADS_OBJECT_BOUND,
IID_IDispatch,
(void **)ppDispatch
);
BAIL_ON_FAILURE(hr);
_dwAttrCurrent++;
RRETURN(S_OK);
}

error:
if (_lpAttrDefs)
SampleDSFreePropertyDefinition(_lpAttrDefs,
_dwAttrReturned);
*ppDispatch = NULL;
RRETURN(S_FALSE);
}