You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
340 lines
7.7 KiB
340 lines
7.7 KiB
//---------------------------------------------------------------------------
|
|
//
|
|
// 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);
|
|
}
|
|
|