//--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1996 - 1997 // // File: cenumobj.cxx // // Contents: IIS Object Enumeration Code // // CIISGenObjectEnum::CIISGenObjectEnum() // CIISGenObjectEnum::CIISGenObjectEnum // CIISGenObjectEnum::Create // CIISGenObjectEnum::GetGenObjects // CIISGenObjectEnum::EnumGenericObjects // CIISGenObjectEnum::Next // // History: 28-Feb-97 SophiaC Created. //---------------------------------------------------------------------------- #include "iis.hxx" #pragma hdrstop //+--------------------------------------------------------------------------- // // Function: CIISEnumVariant::Create // // Synopsis: // // Arguments: [pCollection] // [ppEnumVariant] // // Returns: HRESULT // // Modifies: // // History: // //---------------------------------------------------------------------------- /* INTRINSA suppress=null_pointers, uninitialized */ HRESULT CIISGenObjectEnum::Create( CIISGenObjectEnum FAR* FAR* ppenumvariant, BSTR ADsPath, VARIANT var, CCredentials& Credentials ) { HRESULT hr = NOERROR; CIISGenObjectEnum FAR* penumvariant = NULL; LPWSTR pszIISPathName = NULL; DWORD dwStatus = 0; OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = NULL; CLexer Lexer(ADsPath); *ppenumvariant = NULL; penumvariant = new CIISGenObjectEnum(); if (!penumvariant) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } hr = ADsAllocString( ADsPath, &penumvariant->_ADsPath); BAIL_ON_FAILURE(hr); // // Parse the pathname // pObjectInfo = &ObjectInfo; memset(pObjectInfo, 0, sizeof(OBJECTINFO)); hr = ADsObject(&Lexer, pObjectInfo); BAIL_ON_FAILURE(hr); penumvariant->_Credentials = Credentials; *ppenumvariant = penumvariant; // // Store ServerName // penumvariant->_pszServerName = AllocADsStr(pObjectInfo->TreeName); if (!(penumvariant->_pszServerName)) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } hr = InitServerInfo(Credentials, penumvariant->_pszServerName, &(penumvariant->_pAdminBase), &(penumvariant->_pSchema)); BAIL_ON_FAILURE(hr); pszIISPathName = AllocADsStr(ADsPath); if (!pszIISPathName) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } memset(pszIISPathName, 0, sizeof(pszIISPathName)); hr = BuildIISPathFromADsPath( pObjectInfo, pszIISPathName ); BAIL_ON_FAILURE(hr); penumvariant->_pszMetaBasePath = AllocADsStr(pszIISPathName); if (!(penumvariant->_pszMetaBasePath)) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } error: if (FAILED(hr)) { if (penumvariant) { delete penumvariant; *ppenumvariant = NULL; } } if (pszIISPathName) { FreeADsStr(pszIISPathName); } FreeObjectInfo(pObjectInfo); RRETURN(hr); } CIISGenObjectEnum::CIISGenObjectEnum(): _ADsPath(NULL), _pszServerName(NULL), _pSchema(NULL), _pAdminBase(NULL), _pszMetaBasePath(NULL) { _dwObjectCurrentEntry = 0; } CIISGenObjectEnum::~CIISGenObjectEnum() { if (_ADsPath) { ADsFreeString(_ADsPath); } if (_pszServerName) { FreeADsStr(_pszServerName); } if (_pszMetaBasePath){ FreeADsStr(_pszMetaBasePath); } // // Release everything // } HRESULT CIISGenObjectEnum::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); } /* #pragma INTRINSA suppress=all */ HRESULT CIISGenObjectEnum::GetGenObject( IDispatch ** ppDispatch ) { HRESULT hr = S_OK; WCHAR NameBuf[MAX_PATH]; WCHAR DataBuf[MAX_PATH]; DWORD dwStatus = 0; DWORD dwReqdBufferLen; METADATA_HANDLE hObjHandle = NULL; METADATA_RECORD mdrData; IADs * pADs = NULL; *ppDispatch = NULL; if (!_pAdminBase) { hr = InitServerInfo(_Credentials, _pszServerName, &_pAdminBase, &_pSchema); BAIL_ON_FAILURE(hr); } hr = OpenAdminBaseKey( _Credentials, _pszServerName, _pszMetaBasePath, METADATA_PERMISSION_READ, &_pAdminBase, &hObjHandle ); BAIL_ON_FAILURE(hr); hr = _pAdminBase->EnumKeys( hObjHandle, L"", (LPWSTR)NameBuf, _dwObjectCurrentEntry ); BAIL_ON_FAILURE(hr); // // Find out Class Name // mdrData.dwMDIdentifier = MD_KEY_TYPE; mdrData.dwMDDataType = STRING_METADATA; mdrData.dwMDUserType = ALL_METADATA; mdrData.dwMDAttributes = METADATA_INHERIT; mdrData.dwMDDataLen = MAX_PATH; mdrData.pbMDData = (PBYTE)DataBuf; hr = _pAdminBase->GetData( hObjHandle, (LPWSTR)NameBuf, &mdrData, &dwReqdBufferLen ); if (FAILED(hr)) { if (hr == MD_ERROR_DATA_NOT_FOUND) { LPWSTR pszIISPath; pszIISPath = _wcsupr((LPWSTR)_pszMetaBasePath); if (wcsstr(pszIISPath, L"W3SVC") != NULL) { memcpy((LPWSTR)DataBuf, WEBDIR_CLASS_W, SIZEOF_WEBDIR_CLASS_W); } else if (wcsstr(pszIISPath, L"MSFTPSVC") != NULL) { memcpy((LPWSTR)DataBuf, FTPVDIR_CLASS_W, SIZEOF_FTPVDIR_CLASS_W); } else { memcpy((LPWSTR)DataBuf, DEFAULT_SCHEMA_CLASS_W, SIZEOF_DEFAULT_CLASS_W); } } else { BAIL_ON_FAILURE(hr); } } else { hr = _pSchema->ValidateClassName((LPWSTR)DataBuf); if (hr == E_ADS_SCHEMA_VIOLATION) { memcpy((LPWSTR)DataBuf, DEFAULT_SCHEMA_CLASS_W, SIZEOF_DEFAULT_CLASS_W); } } // // 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 = CIISGenObject::CreateGenericObject( _ADsPath, (LPWSTR)NameBuf, (LPWSTR)DataBuf, _Credentials, ADS_OBJECT_BOUND, IID_IDispatch, (void **)&pADs ); BAIL_ON_FAILURE(hr); hr = pADs->QueryInterface( IID_IDispatch, (void**)ppDispatch ); error: if (_pAdminBase && hObjHandle) { CloseAdminBaseKey(_pAdminBase, hObjHandle); } if (pADs) { pADs->Release(); } // // GetGenObject returns only S_FALSE // if (FAILED(hr)) { hr = S_FALSE; } RRETURN(hr); } //+--------------------------------------------------------------------------- // // Function: CIISGenObjectEnum::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 CIISGenObjectEnum::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); }