home *** CD-ROM | disk | FTP | other *** search
- /*++
-
- Copyright (c) 1996 Microsoft Corporation
-
- Module Name:
-
- CEnumObj.c
-
- Abstract:
-
- Generic Object Enumeration CodeStandard IClassFactory implementation
-
- Author:
-
- Environment:
-
- User mode
-
- Revision History :
-
- --*/
- #include "adssmp.h"
- #pragma hdrstop
-
-
- //+---------------------------------------------------------------------------
- //
- // Function: CSampleDSEnumVariant::Create
- //
- // Synopsis:
- //
- // Arguments: [pCollection]
- // [ppEnumVariant]
- //
- // Returns: HRESULT
- //
- // Modifies:
- //
- // History:
- //
- //----------------------------------------------------------------------------
- HRESULT
- CSampleDSGenObjectEnum::Create(
- CSampleDSGenObjectEnum FAR* FAR* ppenumvariant,
- BSTR ADsPath,
- VARIANT var
- )
- {
- HRESULT hr = NOERROR;
- CSampleDSGenObjectEnum FAR* penumvariant = NULL;
- WCHAR szDSPath[MAX_PATH];
- DWORD dwModificationTime = 0L;
- DWORD dwNumberOfEntries = 0L;
- DWORD dwStatus = 0L;
-
- *ppenumvariant = NULL;
-
- penumvariant = new CSampleDSGenObjectEnum();
- if (!penumvariant) {
- hr = E_OUTOFMEMORY;
- BAIL_ON_FAILURE(hr);
- }
-
- hr = xx_put_BSTR(&penumvariant->_ADsPath, ADsPath);
- BAIL_ON_FAILURE(hr);
-
- hr = BuildDSFilterArray(
- var,
- (LPBYTE *)&penumvariant->_pDSFilterList
- );
- if (FAILED(hr)) {
- penumvariant->_pDSFilterList = NULL;
- }
-
- *ppenumvariant = penumvariant;
-
- hr = BuildDSPathFromADsPath(
- ADsPath,
- szDSPath
- );
- BAIL_ON_FAILURE(hr);
-
- hr = SampleDSOpenObject(
- szDSPath,
- &penumvariant->_hObject,
- NULL,
- REG_DS
- );
- BAIL_ON_FAILURE(hr);
-
- hr = SampleDSRDNEnum(
- &penumvariant->_hEnum,
- penumvariant->_hObject
- );
-
- RRETURN(hr);
-
- error:
- if (penumvariant->_hObject) {
- SampleDSCloseObject(penumvariant->_hObject);
- }
-
- delete penumvariant;
-
- RRETURN(hr);
- }
-
- CSampleDSGenObjectEnum::CSampleDSGenObjectEnum():
- _ADsPath(NULL)
- {
- _pObjList = NULL;
- _dwObjectReturned = 0;
- _dwObjectCurrentEntry = 0;
- _dwObjectTotal = 0;
- _hObject = NULL;
- _hEnum = NULL;
- _lpObjects = NULL;
- _pDSFilterList = NULL;
-
- _bNoMore = FALSE;
- }
-
-
- CSampleDSGenObjectEnum::~CSampleDSGenObjectEnum()
- {
- if (_pDSFilterList) {
- FreeFilterList((LPBYTE)_pDSFilterList);
- }
- }
-
- HRESULT
- CSampleDSGenObjectEnum::EnumObjects(
- DWORD ObjectType,
- ULONG cElements,
- VARIANT FAR * pvar,
- ULONG FAR * pcElementFetched
- )
- {
-
- //
- // Multi-level detection of Objects may not be necessary for DS code
- //
-
- RRETURN(EnumGenericObjects(cElements, pvar, pcElementFetched));
-
- }
- HRESULT
- CSampleDSGenObjectEnum::EnumGenericObjects(
- ULONG cElements,
- VARIANT FAR* pvar,
- ULONG FAR* pcElementFetched
- )
- {
- DWORD i;
- ULONG cRequested = 0;
- ULONG cTotalFetched = 0;
- HRESULT hr;
-
- for (i = 0; i < cElements; i++) {
- VariantInit(&pvar[i]);
- }
- cRequested = cElements;
-
- hr = FetchObjects(cElements, pvar, &cTotalFetched);
-
- if (pcElementFetched) {
- *pcElementFetched = cTotalFetched;
- }
-
- RRETURN(hr);
- }
-
- //
- // Load IDispatch pointers of Next cElements Filtered Objects into pvar array
- //
- HRESULT
- CSampleDSGenObjectEnum::FetchObjects(
-
- ULONG cElements,
- VARIANT FAR* pvar,
- ULONG FAR* pcElementFetched
- )
- {
- HRESULT hr;
- IDispatch *pDispatch = NULL;
- DWORD i = 0;
-
- while (i < cElements) {
-
- hr = FetchNextObject(&pDispatch);
- if (hr == S_FALSE) {
- break;
- }
-
- VariantInit(&pvar[i]);
- pvar[i].vt = VT_DISPATCH;
- pvar[i].pdispVal = pDispatch;
- (*pcElementFetched)++;
- i++;
- }
- return(hr);
- }
- //+---------------------------------------------------------------------------
- //
- // Function: CSampleDSNamespaceEnum::FetchNextObject
- //
- // Synopsis: Gets IDispatch pointer of next object in namespace subject to
- // filter.
- //
- // Arguments: [ppDispatch] -- Pointer to where to return IDispatch pointer.
- //
- // Returns: HRESULT -- S_OK if got the next object
- // -- S_FALSE if not
- //
- // Modifies: [*ppDispatch]
- //
- //----------------------------------------------------------------------------
- HRESULT
- CSampleDSGenObjectEnum::FetchNextObject(
- IDispatch ** ppDispatch
- )
- {
- HRESULT hr;
- LPTSTR lpszObjectRDN=NULL ;
- LPTSTR lpszObjectClass = 0;
- DWORD dwClassId = 0;
- IADs * pADs = NULL;
- *ppDispatch = NULL;
-
- hr = S_OK;
- while (hr == S_OK){
- hr=SampleDSNextRDN(_hEnum,
- &lpszObjectRDN,
- &lpszObjectClass
- );
- if (S_OK==hr &&
- S_OK==IsValidDSFilter(lpszObjectClass)) {
- break;
- }
- }
-
- //
- // Now create and send back the current object
- //
- if (hr == S_OK) {
- hr = CSampleDSGenObject::CreateGenericObject(_ADsPath,
- lpszObjectRDN,
- lpszObjectClass,
- ADS_OBJECT_BOUND,
- IID_IDispatch,
- (void **)ppDispatch
- );
- BAIL_ON_FAILURE(hr);
- }
- else {
- if (_hEnum) {
- SampleDSFreeEnum(_hEnum);
- _hEnum = NULL;
- }
- }
-
- error:
-
- //
- // Free the intermediate pADs pointer.
- //
- if (pADs) {
- pADs->Release();
- }
- if (lpszObjectRDN)
- FreeProvMem(lpszObjectRDN);
- if (lpszObjectClass)
- FreeProvMem(lpszObjectClass);
- RRETURN_ENUM_STATUS(hr);
- }
-
-
- //+---------------------------------------------------------------------------
- //
- // Function: CSampleDSGenObjectEnum::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
- //
- //
- //----------------------------------------------------------------------------
- STDMETHODIMP
- CSampleDSGenObjectEnum::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
- CSampleDSGenObjectEnum::IsValidDSFilter(LPWSTR ObjectName){
-
- if (_pDSFilterList){
- for (DWORD i = 0; i < _pDSFilterList->dwNumberOfFilters; i++) {
-
- if ( !_wcsicmp(ObjectName,_pDSFilterList->Filters[i].lpObjectClass) ) {
- RRETURN(S_OK);
- }
- }
- RRETURN(E_FAIL);
- }
- RRETURN(S_OK);
- }
-
- HRESULT
- BuildDSFilterArray(
- VARIANT var,
- LPBYTE * ppContigFilter
- )
- {
- LONG uDestCount = 0;
- LONG dwSLBound = 0;
- LONG dwSUBound = 0;
- VARIANT v;
- LONG i;
- HRESULT hr = S_OK;
-
- LPDS_FILTER_LIST pDsFilterList = 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)AllocProvMem(
- sizeof(DS_FILTER_LIST)
- - sizeof(DS_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)
- );
- if (!pContigFilter) {
-
- hr = E_FAIL;
- BAIL_ON_FAILURE(hr);
- }
-
- }
-
- pDsFilterList = (LPDS_FILTER_LIST)pContigFilter;
-
- if (!pDsFilterList->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;
- LPDS_FILTER_LIST pDsFilterList = NULL;
- DWORD dwFilterCount = 0;
- LPBYTE pNewContigFilter = NULL;
- LPDS_FILTER pNewEntry = NULL;
-
-
- pszFilter = (LPWSTR)AllocProvStr(lpObjectClass);
- if (!pszFilter) {
- return(pContigFilter);
- }
-
- pDsFilterList = (LPDS_FILTER_LIST)pContigFilter;
-
- dwFilterCount = pDsFilterList->dwNumberOfFilters;
-
- pNewContigFilter = (LPBYTE)ReallocProvMem(
- pContigFilter,
-
- sizeof(DS_FILTER_LIST) +
- (dwFilterCount - 1)* sizeof(DS_FILTER),
-
- sizeof(DS_FILTER_LIST)
- + dwFilterCount * sizeof(DS_FILTER)
- );
- if (!pNewContigFilter) {
- return(pContigFilter);
- }
-
- pNewEntry = (LPDS_FILTER)(pNewContigFilter + sizeof(DS_FILTER_LIST)
- + (dwFilterCount - 1)* sizeof(DS_FILTER));
-
- pNewEntry->lpObjectClass = pszFilter;
-
- pDsFilterList = (LPDS_FILTER_LIST)pNewContigFilter;
-
- pDsFilterList->dwNumberOfFilters = dwFilterCount + 1;
-
- return(pNewContigFilter);
- }
-
- void
- FreeFilterList(
- LPBYTE lpContigFilter
- )
- {
- LPDS_FILTER_LIST lpDsFilterList = (LPDS_FILTER_LIST)lpContigFilter;
- DWORD dwNumFilters = 0;
- LPDS_FILTER lpDsFilter = NULL;
- DWORD i = 0;
-
- dwNumFilters = lpDsFilterList->dwNumberOfFilters;
-
- if (dwNumFilters){
-
- lpDsFilter = (LPDS_FILTER)(lpContigFilter + sizeof(DS_FILTER_LIST)
- - sizeof(DS_FILTER));
-
- for (i = 0; i < dwNumFilters; i++) {
-
- FreeProvStr((lpDsFilter + i)->lpObjectClass);
- }
-
- }
-
- FreeProvMem(lpContigFilter);
- }
-
-
-