|
|
//---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1996 - 1997
//
// File: ctree.cxx
//
// Contents: Microsoft ADs IIS Provider Tree Object
//
// History: 25-Feb-97 SophiaC Created.
//
//----------------------------------------------------------------------------
#include "iis.hxx"
#pragma hdrstop
// Class CIISTree
DEFINE_IDispatch_Implementation(CIISTree) DEFINE_IADs_Implementation(CIISTree)
CIISTree::CIISTree(): _pAdminBase(NULL), _pSchema(NULL), _pPropertyCache(NULL) {
VariantInit(&_vFilter);
ENLIST_TRACKING(CIISTree); }
/* #pragma INTRINSA suppress=all */ HRESULT CIISTree::CreateServerObject( BSTR bstrADsPath, CCredentials& Credentials, DWORD dwObjectState, REFIID riid, void **ppvObj ) { HRESULT hr = S_OK; LPWSTR pszADsParent = NULL; WCHAR szCommonName[MAX_PATH+MAX_PROVIDER_TOKEN_LENGTH];
pszADsParent = AllocADsStr(bstrADsPath);
if (!pszADsParent) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
*pszADsParent = L'\0';
//
// Determine the parent and rdn name
//
hr = BuildADsParentPath( bstrADsPath, pszADsParent, szCommonName );
//
// call the helper function
//
hr = CIISTree::CreateServerObject( pszADsParent, szCommonName, L"user", Credentials, dwObjectState, riid, ppvObj );
error:
if (pszADsParent) { FreeADsStr(pszADsParent); }
RRETURN(hr); }
HRESULT CIISTree::CreateServerObject( BSTR Parent, BSTR CommonName, BSTR ClassName, CCredentials& Credentials, DWORD dwObjectState, REFIID riid, void **ppvObj ) { CIISTree FAR * pTree = NULL; HRESULT hr = S_OK;
hr = AllocateTree(Credentials, &pTree); BAIL_ON_FAILURE(hr);
hr = pTree->InitializeCoreObject( Parent, CommonName, ClassName, L"", CLSID_IISTree, dwObjectState ); BAIL_ON_FAILURE(hr);
hr = pTree->_pPropertyCache->InitializePropertyCache( CommonName ); BAIL_ON_FAILURE(hr);
hr = pTree->QueryInterface(riid, ppvObj); BAIL_ON_FAILURE(hr);
pTree->Release();
RRETURN(hr);
error:
delete pTree; RRETURN(hr); }
CIISTree::~CIISTree( ) { VariantClear(&_vFilter);
delete _pDispMgr;
delete _pPropertyCache; }
STDMETHODIMP CIISTree::QueryInterface(REFIID iid, LPVOID FAR* ppv) { if (IsEqualIID(iid, IID_IUnknown)) { *ppv = (IADs FAR *) this; } else if (IsEqualIID(iid, IID_IADsContainer)) { *ppv = (IADsContainer FAR *) this; } else if (IsEqualIID(iid, IID_IADs)) { *ppv = (IADs FAR *) this; } else if (IsEqualIID(iid, IID_IDispatch)) { *ppv = (IADs FAR *) this; } else { *ppv = NULL; return E_NOINTERFACE; } AddRef(); return NOERROR; }
HRESULT CIISTree::SetInfo() { HRESULT hr = S_OK;
if (GetObjectState() == ADS_OBJECT_UNBOUND) {
hr = IISCreateObject(); BAIL_ON_FAILURE(hr);
//
// If the create succeded, set the object type to bound
//
SetObjectState(ADS_OBJECT_BOUND);
}else {
hr = IISSetObject(); BAIL_ON_FAILURE(hr); }
error:
RRETURN(hr); }
HRESULT CIISTree::IISSetObject() { DWORD dwStatus = 0L; LPWSTR pszIISPathName = NULL; HRESULT hr = S_OK;
hr = BuildIISPathFromADsPath( _ADsPath, &pszIISPathName ); BAIL_ON_FAILURE(hr);
//
// Add Set functionality: sophiac
//
error:
if (pszIISPathName) {
FreeADsStr(pszIISPathName); }
RRETURN(hr); }
HRESULT CIISTree::IISCreateObject() { DWORD dwStatus = 0L; LPWSTR pszIISParentName = NULL; HRESULT hr = S_OK;
hr = BuildIISPathFromADsPath( _Parent, &pszIISParentName ); BAIL_ON_FAILURE(hr);
//
// Add Create functionality: sophiac
//
error:
if (pszIISParentName) {
FreeADsStr(pszIISParentName); }
RRETURN(hr); }
HRESULT CIISTree::GetInfo() { RRETURN(GetInfo(TRUE)); }
HRESULT CIISTree::GetInfo( BOOL fExplicit ) { DWORD dwStatus = 0L; HANDLE hObject = NULL; LPWSTR pszIISPathName = NULL; HRESULT hr;
if (GetObjectState() == ADS_OBJECT_UNBOUND) { hr = E_ADS_OBJECT_UNBOUND; BAIL_ON_FAILURE(hr); }
hr = BuildIISPathFromADsPath( _ADsPath, &pszIISPathName ); BAIL_ON_FAILURE(hr);
//
// Add get functionality : sophiac
//
error:
if (pszIISPathName) {
FreeADsStr(pszIISPathName); }
RRETURN(hr); }
/* IADsContainer methods */
STDMETHODIMP CIISTree::get_Count(long FAR* retval) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISTree::get_Filter(THIS_ VARIANT FAR* pVar) { VariantInit(pVar); RRETURN(VariantCopy(pVar, &_vFilter)); }
STDMETHODIMP CIISTree::put_Filter(THIS_ VARIANT Var) { RRETURN(VariantCopy(&_vFilter, &Var)); }
STDMETHODIMP CIISTree::put_Hints(THIS_ VARIANT Var) { RRETURN( E_NOTIMPL); }
STDMETHODIMP CIISTree::get_Hints(THIS_ VARIANT FAR* pVar) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISTree::GetObject( BSTR ClassName, BSTR RelativeName, IDispatch * FAR* ppObject ) { HRESULT hr = S_OK;
hr = ::RelativeGetObject( _ADsPath, ClassName, RelativeName, _Credentials, ppObject, FALSE );
RRETURN(hr);
}
STDMETHODIMP CIISTree::get__NewEnum( THIS_ IUnknown * FAR* retval ) { HRESULT hr; IUnknown FAR* punkEnum=NULL; IEnumVARIANT * penum = NULL;
*retval = NULL;
hr = CIISTreeEnum::Create( (CIISTreeEnum **)&penum, _ADsPath, _vFilter, _Credentials ); BAIL_ON_FAILURE(hr);
hr = penum->QueryInterface( IID_IUnknown, (VOID FAR* FAR*)retval ); BAIL_ON_FAILURE(hr);
if (penum) { penum->Release(); }
RRETURN(NOERROR);
error:
if (penum) { delete penum; }
RRETURN(hr); }
STDMETHODIMP CIISTree::Create( THIS_ BSTR ClassName, BSTR RelativeName, IDispatch * FAR* ppObject ) { HRESULT hr = S_OK; IADs * pADs = NULL; DWORD dwSyntaxId = 0; OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = &ObjectInfo; //
// Validate if this class really exists in the schema
// and validate that this object can be created in this
// container
//
CLexer Lexer(_ADsPath);
BAIL_ON_FAILURE(hr); memset(pObjectInfo, 0, sizeof(OBJECTINFO)); hr = ADsObject(&Lexer, pObjectInfo); BAIL_ON_FAILURE(hr); hr = InitServerInfo(_Credentials, pObjectInfo->TreeName, &_pAdminBase, &_pSchema); BAIL_ON_FAILURE(hr); hr = _pSchema->ValidateClassName(ClassName); BAIL_ON_FAILURE(hr); hr = CIISGenObject::CreateGenericObject( _ADsPath, RelativeName, ClassName, _Credentials, ADS_OBJECT_UNBOUND, IID_IDispatch, (void **)ppObject ); BAIL_ON_FAILURE(hr); RRETURN(hr); error: RRETURN(hr); }
STDMETHODIMP CIISTree::Delete( THIS_ BSTR bstrClassName, BSTR bstrRelativeName ) { LPWSTR pszIISPathName = NULL; HRESULT hr = S_OK;
hr = BuildIISPathFromADsPath( _ADsPath, &pszIISPathName ); BAIL_ON_FAILURE(hr);
//
//
// Add delete functionality : sophiac
//
error:
if (pszIISPathName) { FreeADsStr(pszIISPathName); }
RRETURN(hr); }
STDMETHODIMP CIISTree::CopyHere( THIS_ BSTR SourceName, BSTR NewName, IDispatch * FAR* ppObject ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISTree::MoveHere( THIS_ BSTR SourceName, BSTR NewName, IDispatch * FAR* ppObject ) { RRETURN(E_NOTIMPL); }
HRESULT CIISTree::AllocateTree( CCredentials& Credentials, CIISTree ** ppTree ) { CIISTree FAR * pTree = NULL; CAggregatorDispMgr FAR * pDispMgr = NULL; CPropertyCache FAR * pPropertyCache = NULL; HRESULT hr = S_OK;
pTree = new CIISTree(); if (pTree == NULL) { hr = E_OUTOFMEMORY; } BAIL_ON_FAILURE(hr);
pDispMgr = new CAggregatorDispMgr; if (pDispMgr == NULL) { hr = E_OUTOFMEMORY; } BAIL_ON_FAILURE(hr);
hr = pDispMgr->LoadTypeInfoEntry( LIBID_ADs, IID_IADs, (IADs *)pTree, DISPID_REGULAR ); BAIL_ON_FAILURE(hr);
hr = pDispMgr->LoadTypeInfoEntry( LIBID_ADs, IID_IADsContainer, (IADsContainer *)pTree, DISPID_NEWENUM ); BAIL_ON_FAILURE(hr);
hr = CPropertyCache::createpropertycache( (CCoreADsObject FAR *)pTree, &pPropertyCache ); BAIL_ON_FAILURE(hr);
pTree->_Credentials = Credentials; pTree->_pPropertyCache = pPropertyCache; pTree->_pDispMgr = pDispMgr; *ppTree = pTree;
RRETURN(hr);
error: if (pDispMgr) { delete pDispMgr; }
if (pTree) { delete pTree; }
RRETURN(hr); }
/* INTRINSA suppress=null_pointers, uninitialized */ STDMETHODIMP CIISTree::Get( THIS_ BSTR bstrName, VARIANT FAR* pvProp ) { HRESULT hr = S_OK; DWORD dwSyntaxId; DWORD dwSyntax; DWORD dwNumValues = 0; LPIISOBJECT pIISSrcObjects = NULL; WCHAR wchName[MAX_PATH];
//
// check if property is a supported property
//
hr = _pSchema->LookupSyntaxID(bstrName, &dwSyntax); BAIL_ON_FAILURE(hr);
//
// check if property is BITMASK type;
// if BITMASK type, get corresponding DWORD flag property
//
if (dwSyntax == IIS_SYNTAX_ID_BOOL_BITMASK || dwSyntax == IIS_SYNTAX_ID_BINARY) { hr = _pSchema->LookupFlagPropName(bstrName, (LPWSTR)wchName); BAIL_ON_FAILURE(hr); }
//
// retrieve data object from cache; if one exists
//
if (dwSyntax == IIS_SYNTAX_ID_BOOL_BITMASK || dwSyntax == IIS_SYNTAX_ID_BINARY) { hr = _pPropertyCache->getproperty( wchName, &dwSyntaxId, &dwNumValues, &pIISSrcObjects ); } else { hr = _pPropertyCache->getproperty( bstrName, &dwSyntaxId, &dwNumValues, &pIISSrcObjects ); } BAIL_ON_FAILURE(hr);
//
// reset it to its syntax id if BITMASK type
//
pIISSrcObjects->IISType = dwSyntax;
//
// translate the IIS objects to variants
//
if (dwNumValues == 1) {
hr = IISTypeToVarTypeCopy( _pSchema, bstrName, pIISSrcObjects, pvProp, FALSE ); }else {
hr = IISTypeToVarTypeCopyConstruct( _pSchema, bstrName, pIISSrcObjects, dwNumValues, pvProp, FALSE );
} BAIL_ON_FAILURE(hr);
error: if (pIISSrcObjects) {
IISTypeFreeIISObjects( pIISSrcObjects, dwNumValues ); }
RRETURN(hr); }
/* INTRINSA suppress=null_pointers, uninitialized */ STDMETHODIMP CIISTree::GetEx( THIS_ BSTR bstrName, VARIANT FAR* pvProp ) { HRESULT hr = S_OK; DWORD dwSyntaxId; DWORD dwSyntax; DWORD dwNumValues = 0; LPIISOBJECT pIISSrcObjects = NULL; WCHAR wchName[MAX_PATH];
//
// check if property is a supported property
//
hr = _pSchema->LookupSyntaxID(bstrName, &dwSyntax); BAIL_ON_FAILURE(hr);
//
// check if property is BITMASK type;
// if BITMASK type, get corresponding DWORD flag property
//
if (dwSyntax == IIS_SYNTAX_ID_BOOL_BITMASK || dwSyntax == IIS_SYNTAX_ID_BINARY) { hr = _pSchema->LookupFlagPropName(bstrName, (LPWSTR)wchName); BAIL_ON_FAILURE(hr); }
//
// retrieve data object from cache; if one exists
//
if (dwSyntax == IIS_SYNTAX_ID_BOOL_BITMASK || dwSyntax == IIS_SYNTAX_ID_BINARY) { hr = _pPropertyCache->getproperty( wchName, &dwSyntaxId, &dwNumValues, &pIISSrcObjects ); } else { hr = _pPropertyCache->getproperty( bstrName, &dwSyntaxId, &dwNumValues, &pIISSrcObjects ); } BAIL_ON_FAILURE(hr);
//
// reset it to its syntax id if BITMASK type
//
pIISSrcObjects->IISType = dwSyntax;
//
// translate the IIS objects to variants
//
hr = IISTypeToVarTypeCopyConstruct( _pSchema, bstrName, pIISSrcObjects, dwNumValues, pvProp, TRUE ); BAIL_ON_FAILURE(hr);
error: if (pIISSrcObjects) {
IISTypeFreeIISObjects( pIISSrcObjects, dwNumValues ); }
RRETURN(hr); }
STDMETHODIMP CIISTree::Put( THIS_ BSTR bstrName, VARIANT vProp ) { HRESULT hr = S_OK; DWORD dwSyntaxId = 0; DWORD dwIndex = 0; LPIISOBJECT pIISDestObjects = NULL; DWORD dwNumValues = 0;
VARIANT * pVarArray = NULL; VARIANT * pvProp = NULL; WCHAR wchName[MAX_PATH];
//
// Issue: How do we handle multi-valued support
//
if ((V_VT(&vProp) & VT_VARIANT) && V_ISARRAY(&vProp)) { if(V_ISBYREF(&vProp)) {
hr = ConvertByRefSafeArrayToVariantArray( vProp, &pVarArray, &dwNumValues ); BAIL_ON_FAILURE(hr); pvProp = pVarArray; } else {
hr = ConvertSafeArrayToVariantArray( vProp, &pVarArray, &dwNumValues ); BAIL_ON_FAILURE(hr); pvProp = pVarArray; } } else {
dwNumValues = 1; pvProp = &vProp; }
//
// Check if this is a legal property and it syntax ID
//
hr = _pSchema->LookupSyntaxID( bstrName, &dwSyntaxId); BAIL_ON_FAILURE(hr);
//
// check if the variant maps to the syntax of this property
//
hr = VarTypeToIISTypeCopyConstruct( dwSyntaxId, pvProp, dwNumValues, &pIISDestObjects, FALSE ); BAIL_ON_FAILURE(hr);
//
// check if property is BITMASK type;
// if BITMASK type, get corresponding DWORD flag property
//
if (dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK) { VARIANT vGetProp; DWORD dwMask; DWORD dwFlagValue;
hr = _pSchema->LookupBitMask(bstrName, &dwMask); BAIL_ON_FAILURE(hr);
//
// get its corresponding DWORD flag value
//
hr = _pSchema->LookupFlagPropName(bstrName, (LPWSTR)wchName); BAIL_ON_FAILURE(hr);
VariantInit(&vGetProp); hr = Get(wchName, &vGetProp); BAIL_ON_FAILURE(hr);
dwFlagValue = V_I4(&vGetProp); if (pIISDestObjects->IISValue.value_1.dwDWORD) { dwFlagValue |= dwMask; } else { dwFlagValue &= ~dwMask; }
pIISDestObjects->IISValue.value_1.dwDWORD = dwFlagValue; pIISDestObjects->IISType = IIS_SYNTAX_ID_DWORD; bstrName = wchName; }
if (dwSyntaxId == IIS_SYNTAX_ID_BINARY) { hr = _pSchema->LookupFlagPropName(bstrName, (LPWSTR)wchName); BAIL_ON_FAILURE(hr); bstrName = wchName; }
//
// Find this property in the cache
//
hr = _pPropertyCache->findproperty( bstrName, &dwIndex );
//
// If this property does not exist in the
// cache, add this property into the cache.
//
if (FAILED(hr)) { hr = _pPropertyCache->addproperty( bstrName, dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK ? IIS_SYNTAX_ID_DWORD : dwSyntaxId, dwNumValues, pIISDestObjects ); //
// If the operation fails for some reason
// move on to the next property
//
BAIL_ON_FAILURE(hr);
}
//
// Now update the property in the cache
//
hr = _pPropertyCache->putproperty( bstrName, CACHE_PROPERTY_MODIFIED, dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK ? IIS_SYNTAX_ID_DWORD : dwSyntaxId, dwNumValues, pIISDestObjects ); BAIL_ON_FAILURE(hr);
error:
if (pIISDestObjects) { IISTypeFreeIISObjects( pIISDestObjects, dwNumValues );
}
if (pVarArray) {
DWORD i = 0;
for (i = 0; i < dwNumValues; i++) { VariantClear(pVarArray + i); } FreeADsMem(pVarArray); }
RRETURN(hr); }
STDMETHODIMP CIISTree::PutEx( THIS_ long lnControlCode, BSTR bstrName, VARIANT vProp ) { HRESULT hr = S_OK; DWORD dwSyntaxId = 0; DWORD dwIndex = 0; LPIISOBJECT pIISDestObjects = NULL; DWORD dwNumValues = 0; DWORD dwFlags = 0;
VARIANT * pVarArray = NULL; VARIANT * pvProp = NULL; WCHAR wchName[MAX_PATH];
switch (lnControlCode) { case ADS_PROPERTY_CLEAR: dwFlags = CACHE_PROPERTY_CLEARED;
pIISDestObjects = NULL; dwNumValues = 0;
break;
case ADS_PROPERTY_UPDATE: dwFlags = CACHE_PROPERTY_MODIFIED;
//
// Now begin the rest of the processing
//
if ((V_VT(&vProp) & VT_VARIANT) && V_ISARRAY(&vProp)) { if (V_ISBYREF(&vProp)) { hr = ConvertByRefSafeArrayToVariantArray( vProp, &pVarArray, &dwNumValues ); BAIL_ON_FAILURE(hr); } else { hr = ConvertSafeArrayToVariantArray( vProp, &pVarArray, &dwNumValues ); BAIL_ON_FAILURE(hr); } pvProp = pVarArray;
}else {
hr = E_FAIL; BAIL_ON_FAILURE(hr); }
//
// check if the variant maps to the syntax of this property
//
hr = VarTypeToIISTypeCopyConstruct( dwSyntaxId, pvProp, dwNumValues, &pIISDestObjects, TRUE ); BAIL_ON_FAILURE(hr);
break;
default: RRETURN(hr = E_ADS_BAD_PARAMETER);
}
//
// check if property is BITMASK type;
// if BITMASK type, get corresponding DWORD flag property
//
if (dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK) { VARIANT vGetProp; DWORD dwMask; DWORD dwFlagValue;
hr = _pSchema->LookupBitMask(bstrName, &dwMask); BAIL_ON_FAILURE(hr);
//
// get its corresponding DWORD flag value
//
hr = _pSchema->LookupFlagPropName(bstrName, (LPWSTR)wchName); BAIL_ON_FAILURE(hr);
VariantInit(&vGetProp); hr = Get(wchName, &vGetProp); BAIL_ON_FAILURE(hr);
dwFlagValue = V_I4(&vGetProp); if (pIISDestObjects->IISValue.value_1.dwDWORD) { dwFlagValue |= dwMask; } else { dwFlagValue &= ~dwMask; }
pIISDestObjects->IISValue.value_1.dwDWORD = dwFlagValue; pIISDestObjects->IISType = IIS_SYNTAX_ID_DWORD; bstrName = wchName; }
if (dwSyntaxId == IIS_SYNTAX_ID_BINARY) { hr = _pSchema->LookupFlagPropName(bstrName, (LPWSTR)wchName); BAIL_ON_FAILURE(hr); bstrName = wchName; }
//
// Find this property in the cache
//
hr = _pPropertyCache->findproperty( bstrName, &dwIndex );
//
// If this property does not exist in the
// cache, add this property into the cache.
//
if (FAILED(hr)) { hr = _pPropertyCache->addproperty( bstrName, dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK ? IIS_SYNTAX_ID_DWORD : dwSyntaxId, dwNumValues, pIISDestObjects ); //
// If the operation fails for some reason
// move on to the next property
//
BAIL_ON_FAILURE(hr);
}
//
// Now update the property in the cache
//
hr = _pPropertyCache->putproperty( bstrName, dwFlags, dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK ? IIS_SYNTAX_ID_DWORD : dwSyntaxId, dwNumValues, pIISDestObjects ); BAIL_ON_FAILURE(hr);
error:
if (pIISDestObjects) { IISTypeFreeIISObjects( pIISDestObjects, dwNumValues );
}
if (pVarArray) {
DWORD i = 0;
for (i = 0; i < dwNumValues; i++) { VariantClear(pVarArray + i); } FreeADsMem(pVarArray); }
RRETURN(hr); }
|