//--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1996 // // File: cenumUserCollection.cxx // // Contents: Windows NT 3.5 UserCollection Enumeration Code // // CLDAPUserCollectionEnum::CLDAPUserCollectionEnum() // CLDAPUserCollectionEnum::CLDAPUserCollectionEnum // CLDAPUserCollectionEnum::EnumObjects // CLDAPUserCollectionEnum::EnumObjects // // History: //---------------------------------------------------------------------------- #include "ldap.hxx" #pragma hdrstop HRESULT BuildADsPathFromLDAPPath( LPWSTR szNamespace, LPWSTR szLdapDN, LPWSTR * ppszADsPathName ); //+--------------------------------------------------------------------------- // // Function: CLDAPEnumVariant::Create // // Synopsis: // // Arguments: [pCollection] // [ppEnumVariant] // // Returns: HRESULT // // Modifies: // // History: 01-30-95 krishnag Created. // //---------------------------------------------------------------------------- HRESULT CLDAPUserCollectionEnum::Create( BSTR bstrUserName, CLDAPUserCollectionEnum FAR* FAR* ppenumvariant, VARIANT var, CCredentials& Credentials ) { HRESULT hr = NOERROR; CLDAPUserCollectionEnum FAR* penumvariant = NULL; DWORD dwSLBound = 0; DWORD dwSUBound = 0; if ( V_VT(&var) == VT_BSTR ) { dwSLBound = 0; dwSUBound = 0; } else { if(!(V_VT(&var) == (VT_VARIANT|VT_ARRAY))) { return(E_FAIL); } // // Check that there is only one dimension in this array // if ((V_ARRAY(&var))->cDims != 1) { hr = E_FAIL; BAIL_ON_FAILURE(hr); } // // We know that this is a valid single dimension array // hr = SafeArrayGetLBound( V_ARRAY(&var), 1, (long FAR *)&dwSLBound ); BAIL_ON_FAILURE(hr); hr = SafeArrayGetUBound( V_ARRAY(&var), 1, (long FAR *)&dwSUBound ); BAIL_ON_FAILURE(hr); } *ppenumvariant = NULL; penumvariant = new CLDAPUserCollectionEnum(); if (!penumvariant) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } hr = ADsAllocString(bstrUserName, &(penumvariant->_bstrUserName)); BAIL_ON_FAILURE(hr); hr = VariantCopy(&(penumvariant->_vMembers), &var); BAIL_ON_FAILURE(hr); penumvariant->_dwSUBound = dwSUBound; penumvariant->_dwSLBound = dwSLBound; penumvariant->_dwIndex = dwSLBound; penumvariant->_Credentials = Credentials; *ppenumvariant = penumvariant; RRETURN(hr); error: delete penumvariant; RRETURN_EXP_IF_ERR(hr); } CLDAPUserCollectionEnum::CLDAPUserCollectionEnum(): _dwSLBound(0), _dwSUBound(0), _dwIndex(0), _bstrUserName(NULL) { VariantInit(&_vMembers); } CLDAPUserCollectionEnum::~CLDAPUserCollectionEnum() { VariantClear(&_vMembers); if ( _bstrUserName ) ADsFreeString( _bstrUserName ); } HRESULT CLDAPUserCollectionEnum::EnumUserMembers( ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched ) { HRESULT hr = S_OK; IDispatch *pDispatch = NULL; DWORD i = 0; while (i < cElements) { hr = GetUserMemberObject(&pDispatch); if (FAILED(hr)) { // // Enumerators support code can only handle S_FALSE and S_OK, // so we cannot return other failure hr's for now. // hr = S_FALSE; } if (hr == S_FALSE) { break; } VariantInit(&pvar[i]); pvar[i].vt = VT_DISPATCH; pvar[i].pdispVal = pDispatch; (*pcElementFetched)++; i++; } RRETURN_EXP_IF_ERR(hr); } HRESULT CLDAPUserCollectionEnum::GetUserMemberObject( IDispatch ** ppDispatch ) { VARIANT v; HRESULT hr = S_OK; TCHAR *pszADsPathName = NULL; IUnknown *pObject = NULL; LPWSTR pszUserName = NULL; LPWSTR pszPassword = NULL; DWORD dwAuthFlags = 0; *ppDispatch = NULL; VariantInit(&v); hr = _Credentials.GetUserName(&pszUserName); BAIL_ON_FAILURE(hr); hr = _Credentials.GetPassword(&pszPassword); BAIL_ON_FAILURE(hr); dwAuthFlags = _Credentials.GetAuthFlags(); if (_dwIndex > _dwSUBound) { hr = S_FALSE; goto error; } while ( TRUE ) { VariantInit(&v); if ( _vMembers.vt == VT_BSTR ) { hr = VariantCopy( &v, &_vMembers ); } else { hr = SafeArrayGetElement( V_ARRAY(&_vMembers), (long FAR *)&_dwIndex, &v ); } BAIL_ON_FAILURE(hr); _dwIndex++; hr = BuildADsPathFromLDAPPath( _bstrUserName, V_BSTR(&v), &pszADsPathName); BAIL_ON_FAILURE(hr); hr = ADsOpenObject( pszADsPathName, pszUserName, pszPassword, dwAuthFlags, IID_IUnknown, (LPVOID *)&pObject ); if ( pszADsPathName ) { FreeADsStr( pszADsPathName ); pszADsPathName = NULL; } VariantClear(&v); // // If we failed to get the current object, continue with the next one // if ( FAILED(hr)) continue; hr = pObject->QueryInterface( IID_IDispatch, (LPVOID *) ppDispatch ); BAIL_ON_FAILURE(hr); hr = S_OK; goto error; } error: if ( pObject ) pObject->Release(); if ( pszADsPathName ) FreeADsStr( pszADsPathName ); if (pszPassword) { SecureZeroMemory(pszPassword, wcslen(pszPassword)*sizeof(WCHAR)); FreeADsStr(pszPassword); } if (pszUserName) { FreeADsStr(pszUserName); } VariantClear(&v); RRETURN(hr); } //+--------------------------------------------------------------------------- // // Function: CLDAPUserCollectionEnum::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 krishnag Created. // //---------------------------------------------------------------------------- STDMETHODIMP CLDAPUserCollectionEnum::Next( ULONG cElements, VARIANT FAR* pvar, ULONG FAR* pcElementFetched ) { ULONG cElementFetched = 0; HRESULT hr = S_OK; hr = EnumUserMembers( cElements, pvar, &cElementFetched ); if (pcElementFetched) { *pcElementFetched = cElementFetched; } RRETURN_EXP_IF_ERR(hr); }