windows-nt/Source/XPSP1/NT/ds/adsi/msext/cenumusr.cxx

347 lines
7.5 KiB
C++
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
//---------------------------------------------------------------------------
//
// 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;
hr = _Credentials.GetUserName(&pszUserName);
BAIL_ON_FAILURE(hr);
hr = _Credentials.GetPassword(&pszPassword);
BAIL_ON_FAILURE(hr);
dwAuthFlags = _Credentials.GetAuthFlags();
*ppDispatch = NULL;
if (_dwIndex > _dwSUBound) {
RRETURN(S_FALSE);
}
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;
}
if (pszPassword) {
FreeADsStr(pszPassword);
pszPassword = NULL;
}
if (pszUserName) {
FreeADsStr(pszUserName);
pszUserName = 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);
pObject->Release();
RRETURN(S_OK);
}
error:
if ( pObject )
pObject->Release();
if ( pszADsPathName )
FreeADsStr( pszADsPathName );
if (pszPassword) {
FreeADsStr(pszPassword);
}
if (pszUserName) {
FreeADsStr(pszUserName);
}
VariantClear(&v);
*ppDispatch = NULL;
RRETURN(S_FALSE);
}
//+---------------------------------------------------------------------------
//
// 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);
}