Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

624 lines
13 KiB

//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995
//
// File: cenumdom.cxx
//
// Contents: NDS Object Enumeration Code
//
// CNDSGenObjectEnum::CNDSGenObjectEnum()
// CNDSGenObjectEnum::CNDSGenObjectEnum
// CNDSGenObjectEnum::EnumObjects
// CNDSGenObjectEnum::EnumObjects
//
// History:
//----------------------------------------------------------------------------
#include "NDS.hxx"
#pragma hdrstop
//+---------------------------------------------------------------------------
//
// Function: CNDSEnumVariant::Create
//
// Synopsis:
//
// Arguments: [pCollection]
// [ppEnumVariant]
//
// Returns: HRESULT
//
// Modifies:
//
// History: 01-30-95 krishnag Created.
//
//----------------------------------------------------------------------------
HRESULT
CNDSGenObjectEnum::Create(
CNDSGenObjectEnum FAR* FAR* ppenumvariant,
BSTR ADsPath,
VARIANT var,
CCredentials& Credentials
)
{
HRESULT hr = S_OK;
CNDSGenObjectEnum FAR* penumvariant = NULL;
if (!ppenumvariant) {
RRETURN(E_FAIL);
}
*ppenumvariant = NULL;
penumvariant = new CNDSGenObjectEnum();
if (!penumvariant) {
hr = E_OUTOFMEMORY;
BAIL_ON_FAILURE(hr);
}
hr = ADsAllocString( ADsPath, &penumvariant->_ADsPath);
BAIL_ON_FAILURE(hr);
hr = BuildNDSFilterArray(
var,
(LPBYTE *)&penumvariant->_pNdsFilterList
);
if (FAILED(hr)) {
penumvariant->_pNdsFilterList = NULL;
}
/*
hr = ObjectTypeList::CreateObjectTypeList(
var,
&penumvariant->_pObjList
);
BAIL_ON_FAILURE(hr);
*/
penumvariant->_Credentials = Credentials;
hr = BuildNDSPathFromADsPath2(
ADsPath,
&penumvariant->_pszTreeName,
&penumvariant->_pszDn
);
BAIL_ON_FAILURE(hr);
hr = ADsNdsOpenContext(
penumvariant->_pszTreeName,
Credentials,
&penumvariant->_hADsContext
);
*ppenumvariant = penumvariant;
RRETURN(hr);
error:
if (penumvariant) {
delete penumvariant;
*ppenumvariant = NULL;
}
RRETURN(hr);
}
CNDSGenObjectEnum::CNDSGenObjectEnum():
_ADsPath(NULL), _pszTreeName(NULL), _pszDn(NULL)
{
_pObjList = NULL;
_dwObjectReturned = 0;
_dwObjectCurrentEntry = 0;
_hOperationData = NULL;
_lpObjects = NULL;
_pNdsFilterList = NULL;
_bNoMore = FALSE;
}
CNDSGenObjectEnum::~CNDSGenObjectEnum()
{
if (_ADsPath) {
ADsFreeString(_ADsPath);
}
if (_pszTreeName) {
FreeADsStr(_pszTreeName);
}
if (_pszDn) {
FreeADsStr(_pszDn);
}
if (_pNdsFilterList) {
FreeFilterList((LPBYTE)_pNdsFilterList);
}
if (_hADsContext) {
ADsNdsCloseContext(_hADsContext);
}
ADsNdsFreeNdsObjInfoList(_lpObjects, _dwObjectReturned);
}
HRESULT
CNDSGenObjectEnum::EnumObjects(
DWORD ObjectType,
ULONG cElements,
VARIANT FAR * pvar,
ULONG FAR * pcElementFetched
)
{
//
// Multi-level detection of Objects may not be necessary for NDS code
//
RRETURN(EnumGenericObjects(cElements, pvar, pcElementFetched));
//
// BugBug- commenting out this layer of code
//
/*
switch (ObjectType) {
default:
RRETURN(EnumObjects(cElements, pvar, pcElementFetched));
} */
}
HRESULT
CNDSGenObjectEnum::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;
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);
}
}
if (pcElementFetched) {
*pcElementFetched = cTotalFetched + cFetchedByPath;
}
RRETURN(hr);
}
HRESULT
CNDSGenObjectEnum::EnumGenericObjects(
ULONG cElements,
VARIANT FAR* pvar,
ULONG FAR* pcElementFetched
)
{
HRESULT hr = S_OK;
IDispatch *pDispatch = NULL;
DWORD i = 0;
while (i < cElements ) {
hr = GetGenObject(&pDispatch);
if (FAILED(hr)) {
continue;
}
if (hr == S_FALSE) {
break;
}
VariantInit(&pvar[i]);
pvar[i].vt = VT_DISPATCH;
pvar[i].pdispVal = pDispatch;
(*pcElementFetched)++;
i++;
}
return(hr);
}
HRESULT
CNDSGenObjectEnum::GetGenObject(
IDispatch ** ppDispatch
)
{
HRESULT hr = S_OK;
PADSNDS_OBJECT_INFO lpCurrentObject = NULL;
IADs * pADs = NULL;
*ppDispatch = NULL;
if (!_hOperationData || (_dwObjectCurrentEntry == _dwObjectReturned)) {
if (_hOperationData) {
ADsNdsFreeNdsObjInfoList(_lpObjects, _dwObjectReturned);
_lpObjects = NULL;
}
_dwObjectCurrentEntry = 0;
_dwObjectReturned = 0;
if (_bNoMore) {
hr = S_FALSE;
goto error;
}
hr = ADsNdsListObjects(
_hADsContext,
_pszDn,
L"",
L"",
NULL,
FALSE,
&_hOperationData
);
BAIL_ON_FAILURE(hr);
if (hr == S_ADS_NOMORE_ROWS) {
_bNoMore = TRUE;
}
hr = ADsNdsGetObjectListFromBuffer(
_hADsContext,
_hOperationData,
&_dwObjectReturned,
&_lpObjects
);
BAIL_ON_FAILURE(hr);
if (_dwObjectReturned == 0 ) {
RRETURN (S_FALSE);
goto error;
}
}
//
// Now send back the current object
//
lpCurrentObject = _lpObjects + _dwObjectCurrentEntry;
//
// Bump up the object count. The instantiation of this object
// may fail; if we come into this function again, we do not want
// to pick up the same object.
//
_dwObjectCurrentEntry++;
hr = CNDSGenObject::CreateGenericObject(
_ADsPath,
lpCurrentObject->szObjectName,
lpCurrentObject->szObjectClass,
_Credentials,
ADS_OBJECT_BOUND,
IID_IADs,
(void **)&pADs
);
BAIL_ON_FAILURE(hr);
//
// InstantiateDerivedObject should addref this pointer for us.
//
hr = InstantiateDerivedObject(
pADs,
_Credentials,
IID_IDispatch,
(void **)ppDispatch
);
if (FAILED(hr)) {
hr = pADs->QueryInterface(
IID_IDispatch,
(void **)ppDispatch
);
BAIL_ON_FAILURE(hr);
}
error:
if (hr == S_FALSE) {
ADsNdsFreeBuffer(_hOperationData);
_hOperationData = NULL;
}
//
// Free the intermediate pADs pointer.
//
if (pADs) {
pADs->Release();
}
RRETURN(hr);
}
//+---------------------------------------------------------------------------
//
// Function: CNDSGenObjectEnum::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
CNDSGenObjectEnum::Next(
ULONG cElements,
VARIANT FAR* pvar,
ULONG FAR* pcElementFetched
)
{
ULONG cElementFetched = 0;
HRESULT hr = S_OK;
hr = EnumGenericObjects(
cElements,
pvar,
&cElementFetched
);
if (pcElementFetched) {
*pcElementFetched = cElementFetched;
}
RRETURN(hr);
}
HRESULT
BuildNDSFilterArray(
VARIANT var,
LPBYTE * ppContigFilter
)
{
LONG uDestCount = 0;
LONG dwSLBound = 0;
LONG dwSUBound = 0;
VARIANT v;
LONG i;
HRESULT hr = S_OK;
LPNDS_FILTER_LIST pNdsFilterList = NULL;
LPBYTE pContigFilter = NULL;
if(!((V_VT(&var) & VT_VARIANT) && V_ISARRAY(&var))) {
RRETURN(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);
}
//
// Check that there is atleast one element in this array
//
if ((V_ARRAY(&var))->rgsabound[0].cElements == 0){
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);
pContigFilter = (LPBYTE)AllocADsMem(
sizeof(NDS_FILTER_LIST)
- sizeof(NDS_FILTER)
);
if (!pContigFilter) {
hr = E_FAIL;
BAIL_ON_FAILURE(hr);
}
for (i = dwSLBound; i <= dwSUBound; i++) {
VariantInit(&v);
hr = SafeArrayGetElement(V_ARRAY(&var),
(long FAR *)&i,
&v
);
if (FAILED(hr)) {
continue;
}
//
// Create an entry in the filter block
// Append it to the existing block
//
pContigFilter = CreateAndAppendFilterEntry(
pContigFilter,
V_BSTR(&v)
);
VariantClear(&v);
if (!pContigFilter) {
hr = E_FAIL;
BAIL_ON_FAILURE(hr);
}
}
pNdsFilterList = (LPNDS_FILTER_LIST)pContigFilter;
if (!pNdsFilterList->dwNumberOfFilters){
hr = E_FAIL;
BAIL_ON_FAILURE(hr);
}
*ppContigFilter = pContigFilter;
RRETURN(S_OK);
error:
if (pContigFilter){
FreeFilterList(
pContigFilter
);
}
*ppContigFilter = NULL;
RRETURN(hr);
}
LPBYTE
CreateAndAppendFilterEntry(
LPBYTE pContigFilter,
LPWSTR lpObjectClass
)
{
LPWSTR pszFilter = NULL;
LPNDS_FILTER_LIST pNdsFilterList = NULL;
DWORD dwFilterCount = 0;
LPBYTE pNewContigFilter = NULL;
LPNDS_FILTER pNewEntry = NULL;
pszFilter = (LPWSTR)AllocADsStr(lpObjectClass);
if (!pszFilter) {
return(pContigFilter);
}
pNdsFilterList = (LPNDS_FILTER_LIST)pContigFilter;
dwFilterCount = pNdsFilterList->dwNumberOfFilters;
pNewContigFilter = (LPBYTE)ReallocADsMem(
pContigFilter,
sizeof(NDS_FILTER_LIST) +
(dwFilterCount - 1)* sizeof(NDS_FILTER),
sizeof(NDS_FILTER_LIST)
+ dwFilterCount * sizeof(NDS_FILTER)
);
if (!pNewContigFilter) {
return(pContigFilter);
}
pNewEntry = (LPNDS_FILTER)(pNewContigFilter + sizeof(NDS_FILTER_LIST)
+ (dwFilterCount - 1)* sizeof(NDS_FILTER));
pNewEntry->szObjectClass = pszFilter;
pNdsFilterList = (LPNDS_FILTER_LIST)pNewContigFilter;
pNdsFilterList->dwNumberOfFilters = dwFilterCount + 1;
return(pNewContigFilter);
}
void
FreeFilterList(
LPBYTE lpContigFilter
)
{
LPNDS_FILTER_LIST lpNdsFilterList = (LPNDS_FILTER_LIST)lpContigFilter;
DWORD dwNumFilters = 0;
LPNDS_FILTER lpNdsFilter = NULL;
DWORD i = 0;
dwNumFilters = lpNdsFilterList->dwNumberOfFilters;
if (dwNumFilters){
lpNdsFilter = (LPNDS_FILTER)(lpContigFilter + sizeof(NDS_FILTER_LIST)
- sizeof(NDS_FILTER));
for (i = 0; i < dwNumFilters; i++) {
FreeADsStr((lpNdsFilter + i)->szObjectClass);
}
}
FreeADsMem(lpContigFilter);
}