WindowsXP-SP1/ds/adsi/ldap/cenumsch.cxx

508 lines
12 KiB
C++

//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996
//
// File: cenumsch.cxx
//
// Contents: LDAP Schema Enumeration Code
//
// CLDAPSchemaEnum::CLDAPSchemaEnum()
// CLDAPSchemaEnum::CLDAPSchemaEnum
// CLDAPSchemaEnum::EnumObjects
// CLDAPSchemaEnum::EnumObjects
//
// History:
//----------------------------------------------------------------------------
#include "ldap.hxx"
#pragma hdrstop
//+---------------------------------------------------------------------------
//
// Function: CLDAPSchemaEnum::Create
//
// Synopsis:
//
// Arguments: [pCollection]
// [ppEnumVariant]
//
// Returns: HRESULT
//
// Modifies:
//
// History: 01-30-95 yihsins Created.
//
//----------------------------------------------------------------------------
HRESULT
CLDAPSchemaEnum::Create(
CLDAPSchemaEnum FAR* FAR* ppenumvariant,
BSTR bstrADsPath,
BSTR bstrServerPath,
VARIANT vFilter,
CCredentials& Credentials
)
{
HRESULT hr = S_OK;
CLDAPSchemaEnum FAR* penumvariant = NULL;
OBJECTINFO ObjectInfo;
POBJECTINFO pObjectInfo = &ObjectInfo;
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
*ppenumvariant = NULL;
penumvariant = new CLDAPSchemaEnum();
if (!penumvariant)
{
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
hr = ADsAllocString( bstrADsPath, &penumvariant->_bstrADsPath);
BAIL_ON_FAILURE(hr);
hr = ADsAllocString( bstrServerPath, &penumvariant->_bstrServerPath);
BAIL_ON_FAILURE(hr);
hr = ADsObject(bstrADsPath, pObjectInfo);
BAIL_ON_FAILURE(hr);
hr = SchemaOpen(
bstrServerPath,
&(penumvariant->_hSchema),
Credentials,
pObjectInfo->PortNumber
);
BAIL_ON_FAILURE(hr);
hr = SchemaGetObjectCount(
penumvariant->_hSchema,
&(penumvariant->_nNumOfClasses),
&(penumvariant->_nNumOfProperties) );
BAIL_ON_FAILURE(hr);
hr = ObjectTypeList::CreateObjectTypeList(
vFilter,
&penumvariant->_pObjList );
BAIL_ON_FAILURE(hr);
penumvariant->_Credentials = Credentials;
*ppenumvariant = penumvariant;
FreeObjectInfo(pObjectInfo);
RRETURN(hr);
error:
FreeObjectInfo(pObjectInfo);
delete penumvariant;
RRETURN_EXP_IF_ERR(hr);
}
CLDAPSchemaEnum::CLDAPSchemaEnum()
: _bstrADsPath( NULL ),
_bstrServerPath( NULL ),
_hSchema( NULL ),
_pObjList( NULL ),
_dwCurrentEntry( 0 ),
_nNumOfClasses( 0 ),
_nNumOfProperties( 0 )
{
}
CLDAPSchemaEnum::~CLDAPSchemaEnum()
{
ADsFreeString( _bstrADsPath );
ADsFreeString( _bstrServerPath );
if ( _hSchema )
{
SchemaClose( &_hSchema );
}
if ( _pObjList != NULL )
{
delete _pObjList;
_pObjList = NULL;
}
}
//+---------------------------------------------------------------------------
//
// Function: CLDAPSchemaEnum::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
CLDAPSchemaEnum::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_EXP_IF_ERR(hr);
}
HRESULT
CLDAPSchemaEnum::EnumObjects(
DWORD ObjectType,
ULONG cElements,
VARIANT FAR * pvar,
ULONG FAR * pcElementFetched
)
{
HRESULT hr;
switch (ObjectType)
{
case LDAP_CLASS_ID:
hr = EnumClasses(cElements, pvar, pcElementFetched);
break;
case LDAP_PROPERTY_ID:
hr = EnumProperties(cElements, pvar, pcElementFetched);
break;
case LDAP_SYNTAX_ID:
hr = EnumSyntaxObjects(cElements, pvar, pcElementFetched);
break;
default:
hr = S_FALSE;
}
RRETURN(hr);
}
HRESULT
CLDAPSchemaEnum::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_FALSE;
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_EXP_IF_ERR(hr);
}
HRESULT
CLDAPSchemaEnum::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
CLDAPSchemaEnum::GetClassObject(
IDispatch ** ppDispatch
)
{
HRESULT hr = S_OK;
CLASSINFO *pClassInfo = NULL;
//
// Now send back the current object
//
if ( _dwCurrentEntry >= _nNumOfClasses )
goto error;
hr = SchemaGetClassInfoByIndex(
_hSchema,
_dwCurrentEntry,
&pClassInfo );
BAIL_ON_FAILURE(hr);
if (_Credentials.GetAuthFlags() & ADS_AUTH_RESERVED) {
//
// If we are in Umi land, then we cannot ask for dispatch.
//
hr = CLDAPClass::CreateClass(
_bstrADsPath,
_hSchema,
pClassInfo->pszName,
pClassInfo,
_Credentials,
ADS_OBJECT_BOUND,
IID_IUnknown,
(void **) ppDispatch
);
}
else {
hr = CLDAPClass::CreateClass(
_bstrADsPath,
_hSchema,
pClassInfo->pszName,
pClassInfo,
_Credentials,
ADS_OBJECT_BOUND,
IID_IDispatch,
(void **)ppDispatch
);
}
BAIL_ON_FAILURE(hr);
_dwCurrentEntry++;
RRETURN(S_OK);
error:
*ppDispatch = NULL;
RRETURN(S_FALSE);
}
HRESULT
CLDAPSchemaEnum::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
CLDAPSchemaEnum::GetPropertyObject(
IDispatch ** ppDispatch
)
{
HRESULT hr = S_OK;
PROPERTYINFO *pPropertyInfo = NULL;
//
// Now send back the current object
//
if ( _dwCurrentEntry >= _nNumOfProperties )
goto error;
hr = SchemaGetPropertyInfoByIndex(
_hSchema,
_dwCurrentEntry,
&pPropertyInfo );
BAIL_ON_FAILURE(hr);
if (_Credentials.GetAuthFlags() & ADS_AUTH_RESERVED) {
//
// In Umi land ask for IID_IUnknown.
//
hr = CLDAPProperty::CreateProperty(
_bstrADsPath,
_hSchema,
pPropertyInfo->pszPropertyName,
pPropertyInfo,
_Credentials,
ADS_OBJECT_BOUND,
IID_IUnknown,
(void **)ppDispatch
);
}
else {
hr = CLDAPProperty::CreateProperty(
_bstrADsPath,
_hSchema,
pPropertyInfo->pszPropertyName,
pPropertyInfo,
_Credentials,
ADS_OBJECT_BOUND,
IID_IDispatch,
(void **)ppDispatch
);
}
BAIL_ON_FAILURE(hr);
_dwCurrentEntry++;
RRETURN(S_OK);
error:
*ppDispatch = NULL;
RRETURN(S_FALSE);
}
HRESULT
CLDAPSchemaEnum::EnumSyntaxObjects(
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
CLDAPSchemaEnum::GetSyntaxObject(
IDispatch ** ppDispatch
)
{
HRESULT hr = S_OK;
//
// Now send back the current object
//
if ( _dwCurrentEntry >= g_cLDAPSyntax )
goto error;
if (_Credentials.GetAuthFlags() & ADS_AUTH_RESERVED) {
//
// In Umi land ask for IID_IUnknown not dispatch.
//
hr = CLDAPSyntax::CreateSyntax(
_bstrADsPath,
&g_aLDAPSyntax[_dwCurrentEntry],
_Credentials,
ADS_OBJECT_BOUND,
IID_IUnknown,
(void **)ppDispatch
);
}
else {
hr = CLDAPSyntax::CreateSyntax(
_bstrADsPath,
&g_aLDAPSyntax[_dwCurrentEntry],
_Credentials,
ADS_OBJECT_BOUND,
IID_IDispatch,
(void **)ppDispatch
);
}
BAIL_ON_FAILURE(hr);
_dwCurrentEntry++;
RRETURN(S_OK);
error:
*ppDispatch = NULL;
RRETURN(S_FALSE);
}