//--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1995 // // File: cenumsch.cxx // // Contents: NDS Schema Enumeration Code // // CNDSSchemaEnum::CNDSSchemaEnum() // CNDSSchemaEnum::CNDSSchemaEnum // CNDSSchemaEnum::EnumObjects // CNDSSchemaEnum::EnumObjects // // History: //---------------------------------------------------------------------------- #include "NDS.hxx" #pragma hdrstop //+--------------------------------------------------------------------------- // // Function: CNDSSchemaEnum::Create // // Synopsis: // // Arguments: [pCollection] // [ppEnumVariant] // // Returns: HRESULT // // Modifies: // // History: 01-30-95 yihsins Created. // //---------------------------------------------------------------------------- HRESULT CNDSSchemaEnum::Create( CNDSSchemaEnum FAR* FAR* ppenumvariant, BSTR bstrNDSTreeName, BSTR bstrADsPath, BSTR bstrName, VARIANT var, CCredentials& Credentials ) { HRESULT hr = S_OK; CNDSSchemaEnum FAR* penumvariant = NULL; *ppenumvariant = NULL; penumvariant = new CNDSSchemaEnum(); if (!penumvariant) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } hr = ADsAllocString( bstrNDSTreeName, &penumvariant->_bstrNDSTreeName); BAIL_ON_FAILURE(hr); hr = ADsNdsOpenContext( penumvariant->_bstrNDSTreeName, Credentials, &penumvariant->_hADsContext ); BAIL_ON_FAILURE(hr); hr = ADsAllocString( bstrADsPath, &penumvariant->_bstrADsPath); BAIL_ON_FAILURE(hr); hr = ADsAllocString( bstrName, &penumvariant->_bstrName); BAIL_ON_FAILURE(hr); hr = ObjectTypeList::CreateObjectTypeList( var, &penumvariant->_pObjList ); BAIL_ON_FAILURE(hr); penumvariant->_Credentials = Credentials; *ppenumvariant = penumvariant; RRETURN(hr); error: delete penumvariant; RRETURN(hr); } CNDSSchemaEnum::CNDSSchemaEnum() : _bstrADsPath( NULL ), _bstrName( NULL ), _bstrNDSTreeName( NULL ), _pObjList( NULL ), _dwCurrentEntry( 0 ), _dwSyntaxCurrentEntry( 0 ) { _hOperationData = NULL; _hADsContext = NULL; _lpClassDefs = NULL; _dwObjectCurrentEntry = 0; _dwObjectReturned = 0; _dwInfoType = 0; _dwPropCurrentEntry = 0; _hPropOperationData = NULL; _lpAttrDefs = NULL; _dwPropObjectCurrentEntry = 0; _dwPropObjectReturned = 0; _dwPropInfoType = 0; _bNoMore = FALSE; _bNoMoreProp = FALSE; } CNDSSchemaEnum::~CNDSSchemaEnum() { ADsFreeString( _bstrName ); ADsFreeString( _bstrADsPath ); ADsFreeString( _bstrNDSTreeName ); ADsNdsFreeClassDefList(_lpClassDefs, _dwObjectReturned); ADsNdsFreeAttrDefList(_lpAttrDefs, _dwPropObjectReturned); ADsNdsFreeBuffer( _hOperationData ); ADsNdsFreeBuffer( _hPropOperationData ); if (_hADsContext) { ADsNdsCloseContext(_hADsContext); } if ( _pObjList != NULL ) { delete _pObjList; _pObjList = NULL; } } //+--------------------------------------------------------------------------- // // Function: CNDSSchemaEnum::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 CNDSSchemaEnum::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 CNDSSchemaEnum::EnumObjects( DWORD ObjectType, ULONG cElements, VARIANT FAR * pvar, ULONG FAR * pcElementFetched ) { switch (ObjectType) { case NDS_CLASS_ID: RRETURN (EnumClasses(cElements, pvar, pcElementFetched)); case NDS_PROPERTY_ID: RRETURN (EnumProperties(cElements, pvar, pcElementFetched)); case NDS_SYNTAX_ID: RRETURN(EnumSyntaxes(cElements, pvar, pcElementFetched)); default: RRETURN(S_FALSE); } } HRESULT CNDSSchemaEnum::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 = S_OK; 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); } _dwCurrentEntry = 0; } if ( pcElementFetched ) *pcElementFetched = cTotalFetched + cFetchedByPath; RRETURN(hr); } HRESULT CNDSSchemaEnum::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 CNDSSchemaEnum::GetClassObject( IDispatch ** ppDispatch ) { HRESULT hr = S_OK; PNDS_CLASS_DEF lpCurrentObject = NULL; if (!_hOperationData || (_dwObjectCurrentEntry == _dwObjectReturned)) { _dwObjectCurrentEntry = 0; _dwObjectReturned = 0; if (_hOperationData) { ADsNdsFreeClassDefList(_lpClassDefs, _dwObjectReturned); _lpClassDefs = NULL; } if (_bNoMore) { hr = S_FALSE; goto error; } hr = ADsNdsReadClassDef( _hADsContext, DS_CLASS_DEFS, NULL, (DWORD) -1, &_hOperationData ); BAIL_ON_FAILURE(hr); if (hr == S_ADS_NOMORE_ROWS) { _bNoMore = TRUE; } hr = ADsNdsGetClassDefListFromBuffer( _hADsContext, _hOperationData, &_dwObjectReturned, &_dwInfoType, &_lpClassDefs ); BAIL_ON_FAILURE(hr); if (_dwObjectReturned == 0 ) { RRETURN (S_FALSE); goto error; } } if (_dwObjectCurrentEntry < _dwObjectReturned) { // // Now send back the current object // lpCurrentObject = _lpClassDefs + _dwObjectCurrentEntry; hr = CNDSClass::CreateClass( _bstrADsPath, lpCurrentObject->szClassName, lpCurrentObject, _Credentials, ADS_OBJECT_BOUND, IID_IDispatch, (void **)ppDispatch ); BAIL_ON_FAILURE(hr); _dwObjectCurrentEntry++; RRETURN(S_OK); } error: *ppDispatch = NULL; RRETURN(S_FALSE); } HRESULT CNDSSchemaEnum::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 CNDSSchemaEnum::GetPropertyObject( IDispatch ** ppDispatch ) { HRESULT hr = S_OK; LPNDS_ATTR_DEF lpCurrentPropObject = NULL; DWORD dwStatus; if (!_hPropOperationData || (_dwPropObjectCurrentEntry == _dwPropObjectReturned)) { _dwPropObjectCurrentEntry = 0; _dwPropObjectReturned = 0; if (_hPropOperationData) { ADsNdsFreeAttrDefList(_lpAttrDefs, _dwPropObjectReturned); _lpAttrDefs = NULL; } if (_bNoMoreProp) { hr = S_FALSE; goto error; } hr = ADsNdsReadAttrDef( _hADsContext, DS_ATTR_DEFS, NULL, (DWORD) -1, &_hPropOperationData ); BAIL_ON_FAILURE(hr); if (hr == S_ADS_NOMORE_COLUMNS) { _bNoMoreProp = TRUE; } hr = ADsNdsGetAttrDefListFromBuffer( _hADsContext, _hPropOperationData, &_dwPropObjectReturned, &_dwInfoType, &_lpAttrDefs ); BAIL_ON_FAILURE(hr); if (_dwPropObjectReturned == 0 ) { RRETURN (S_FALSE); goto error; } } if (_dwPropObjectCurrentEntry < _dwPropObjectReturned) { // // Now send back the current object // lpCurrentPropObject = _lpAttrDefs + _dwPropObjectCurrentEntry; hr = CNDSProperty::CreateProperty( _bstrADsPath, lpCurrentPropObject->szAttributeName, lpCurrentPropObject, _Credentials, ADS_OBJECT_BOUND, IID_IDispatch, (void **)ppDispatch ); BAIL_ON_FAILURE(hr); _dwPropObjectCurrentEntry++; RRETURN(S_OK); } error: *ppDispatch = NULL; RRETURN(S_FALSE); } HRESULT CNDSSchemaEnum::EnumSyntaxes( ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched ) { HRESULT hr = S_OK; DWORD i = 0; IDispatch *pDispatch = NULL; while ( i < cElements ) { hr = GetSyntaxObject(&pDispatch); if ( hr == S_FALSE ) break; VariantInit( &pvar[i] ); pvar[i].vt = VT_DISPATCH; pvar[i].pdispVal = pDispatch; (*pcElementFetched)++; i++; } RRETURN(hr); } HRESULT CNDSSchemaEnum::GetSyntaxObject( IDispatch ** ppDispatch ) { HRESULT hr = S_OK; // // Now send back the current object // if ( _dwSyntaxCurrentEntry >= g_cNDSSyntax ) goto error; hr = CNDSSyntax::CreateSyntax( _bstrADsPath, &g_aNDSSyntax[_dwSyntaxCurrentEntry], ADS_OBJECT_BOUND, IID_IDispatch, (void **)ppDispatch ); BAIL_ON_FAILURE(hr); _dwSyntaxCurrentEntry++; RRETURN(S_OK); error: *ppDispatch = NULL; RRETURN(S_FALSE); }