|
|
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996
//
// File: cschema.cxx
//
// Contents: Windows NT 4.0
//
//
// History: 01-09-98 sophiac Created.
//
//----------------------------------------------------------------------------
#include "iis.hxx"
#pragma hdrstop
#define PROP_RW 0x0000001
SCHEMAOBJPROPS g_pClassObjProps[] = { {L"PrimaryInterface", IIS_SYNTAX_ID_STRING, CLASS_PRIMARY_INTERFACE}, {L"CLSID", IIS_SYNTAX_ID_STRING, CLASS_CLSID}, {L"OID", IIS_SYNTAX_ID_STRING, CLASS_OID}, {L"Abstract", IIS_SYNTAX_ID_BOOL, CLASS_ABSTRACT}, {L"Auxiliary", IIS_SYNTAX_ID_BOOL, CLASS_AUXILIARY}, {L"MandatoryProperties", IIS_SYNTAX_ID_STRING, CLASS_MAND_PROPERTIES}, {L"OptionalProperties", IIS_SYNTAX_ID_STRING, CLASS_OPT_PROPERTIES}, {L"NamingProperties", IIS_SYNTAX_ID_STRING, CLASS_NAMING_PROPERTIES}, {L"DerivedFrom", IIS_SYNTAX_ID_STRING, CLASS_DERIVEDFROM}, {L"AuxDerivedFrom", IIS_SYNTAX_ID_STRING, CLASS_AUX_DERIVEDFROM}, {L"PossibleSuperiors", IIS_SYNTAX_ID_STRING, CLASS_POSS_SUPERIORS}, {L"Containment", IIS_SYNTAX_ID_STRING, CLASS_CONTAINMENT}, {L"Container", IIS_SYNTAX_ID_BOOL, CLASS_CONTAINER}, {L"HelpFileName", IIS_SYNTAX_ID_STRING, CLASS_HELPFILENAME}, {L"HelpFileContext", IIS_SYNTAX_ID_DWORD, CLASS_HELPFILECONTEXT} };
SCHEMAOBJPROPS g_pPropertyObjProps[] = { {L"OID", IIS_SYNTAX_ID_STRING, PROP_OID}, {L"Syntax", IIS_SYNTAX_ID_STRING, PROP_SYNTAX}, {L"MaxRange", IIS_SYNTAX_ID_DWORD, PROP_MAXRANGE}, {L"MinRange", IIS_SYNTAX_ID_DWORD, PROP_MINRANGE}, {L"MultiValued", IIS_SYNTAX_ID_BOOL, PROP_MULTIVALUED}, {L"PropName", IIS_SYNTAX_ID_STRING, PROP_PROPNAME}, {L"MetaId", IIS_SYNTAX_ID_DWORD, PROP_METAID}, {L"UserType", IIS_SYNTAX_ID_DWORD, PROP_USERTYPE}, {L"AllAttributes", IIS_SYNTAX_ID_DWORD, PROP_ALLATTRIBUTES}, {L"Inherit", IIS_SYNTAX_ID_BOOL, PROP_INHERIT}, {L"PartialPath", IIS_SYNTAX_ID_BOOL, PROP_PARTIALPATH}, {L"Secure", IIS_SYNTAX_ID_BOOL, PROP_SECURE}, {L"Reference", IIS_SYNTAX_ID_BOOL, PROP_REFERENCE}, {L"Volatile", IIS_SYNTAX_ID_BOOL, PROP_VOLATILE}, {L"Isinherit", IIS_SYNTAX_ID_BOOL, PROP_ISINHERIT}, {L"InsertPath", IIS_SYNTAX_ID_BOOL, PROP_INSERTPATH}, {L"Default", IIS_SYNTAX_ID_STRING_DWORD, PROP_DEFAULT} };
DWORD g_cPropertyObjProps (sizeof(g_pPropertyObjProps)/sizeof(SCHEMAOBJPROPS)); DWORD g_cClassObjProps (sizeof(g_pClassObjProps)/sizeof(SCHEMAOBJPROPS));
/******************************************************************/ /* Class CIISClass
/******************************************************************/
DEFINE_IDispatch_Implementation(CIISClass) DEFINE_IADs_Implementation(CIISClass)
CIISClass::CIISClass() : _pDispMgr( NULL ), _bstrCLSID( NULL ), _bstrOID( NULL ), _bstrPrimaryInterface( NULL ), _fAbstract( FALSE ), _fContainer( FALSE ), _bstrHelpFileName( NULL ), _lHelpFileContext( 0 ), _bExistClass(FALSE), _pSchema(NULL), _pszServerName(NULL), _pszClassName(NULL), _pAdminBase(NULL) { VariantInit( &_vMandatoryProperties ); VariantInit( &_vOptionalProperties ); VariantInit( &_vPossSuperiors ); VariantInit( &_vContainment );
ENLIST_TRACKING(CIISClass); }
CIISClass::~CIISClass() {
if ( _bstrCLSID ) { ADsFreeString( _bstrCLSID ); }
if ( _bstrOID ) { ADsFreeString( _bstrOID ); }
if ( _bstrPrimaryInterface ) { ADsFreeString( _bstrPrimaryInterface ); }
if ( _bstrHelpFileName ) { ADsFreeString( _bstrHelpFileName ); }
if (_pszServerName) { FreeADsStr(_pszServerName); }
if (_pszClassName) { FreeADsStr(_pszClassName); }
VariantClear( &_vMandatoryProperties ); VariantClear( &_vOptionalProperties ); VariantClear( &_vPossSuperiors ); VariantClear( &_vContainment );
delete _pDispMgr; }
HRESULT CIISClass::CreateClass( BSTR bstrParent, BSTR bstrRelative, DWORD dwObjectState, REFIID riid, void **ppvObj ) { CIISClass FAR *pClass = NULL; HRESULT hr = S_OK; CCredentials localCred; BSTR bstrTmp = NULL; CLASSINFO *pClassInfo; OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = &ObjectInfo; CLexer Lexer(bstrParent);
memset(pObjectInfo, 0, sizeof(OBJECTINFO));
hr = AllocateClassObject( &pClass ); BAIL_ON_FAILURE(hr);
hr = ADsObject(&Lexer, pObjectInfo); BAIL_ON_FAILURE(hr);
hr = InitServerInfo(localCred, pObjectInfo->TreeName, &pClass->_pAdminBase, &pClass->_pSchema); BAIL_ON_FAILURE(hr);
pClass->_pszServerName = AllocADsStr(pObjectInfo->TreeName);
if (!pClass->_pszServerName) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
pClass->_pszClassName = AllocADsStr(bstrRelative);
if (!pClass->_pszClassName) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
pClassInfo = pClass->_pSchema->GetClassInfo(bstrRelative);
//
// an existing class
//
if (pClassInfo) { pClass->_bExistClass = TRUE; pClass->_lHelpFileContext = pClassInfo->lHelpFileContext; pClass->_fContainer = (VARIANT_BOOL)pClassInfo->fContainer; pClass->_fAbstract = (VARIANT_BOOL)pClassInfo->fAbstract;
if (pClassInfo->pPrimaryInterfaceGUID) { hr = StringFromCLSID( (REFCLSID) *(pClassInfo->pPrimaryInterfaceGUID), &bstrTmp ); BAIL_ON_FAILURE(hr);
hr = ADsAllocString( bstrTmp, &pClass->_bstrPrimaryInterface); BAIL_ON_FAILURE(hr);
CoTaskMemFree(bstrTmp); bstrTmp = NULL; }
if (pClassInfo->pCLSID) { hr = StringFromCLSID( (REFCLSID) *(pClassInfo->pCLSID), &bstrTmp ); BAIL_ON_FAILURE(hr); hr = ADsAllocString( bstrTmp, &pClass->_bstrCLSID ); BAIL_ON_FAILURE(hr);
CoTaskMemFree(bstrTmp); bstrTmp = NULL; }
hr = ADsAllocString( pClassInfo->bstrOID, &pClass->_bstrOID); BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringList( pClassInfo->bstrMandatoryProperties, &(pClass->_vMandatoryProperties)); BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringList( pClassInfo->bstrOptionalProperties, &(pClass->_vOptionalProperties)); BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringList( pClassInfo->bstrPossSuperiors, &(pClass->_vPossSuperiors)); BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringList( pClassInfo->bstrContainment, &(pClass->_vContainment)); BAIL_ON_FAILURE(hr);
hr = ADsAllocString(pClassInfo->bstrHelpFileName, &pClass->_bstrHelpFileName); BAIL_ON_FAILURE(hr); }
hr = pClass->InitializeCoreObject( bstrParent, bstrRelative, CLASS_CLASS_NAME, NO_SCHEMA, CLSID_IISClass, dwObjectState );
BAIL_ON_FAILURE(hr);
hr = pClass->QueryInterface( riid, ppvObj ); BAIL_ON_FAILURE(hr);
pClass->Release();
FreeObjectInfo(pObjectInfo);
RRETURN(hr);
error:
if ( bstrTmp != NULL ) CoTaskMemFree(bstrTmp);
*ppvObj = NULL; delete pClass;
FreeObjectInfo(pObjectInfo);
RRETURN(hr); }
STDMETHODIMP CIISClass::QueryInterface(REFIID iid, LPVOID FAR* ppv) { if (IsEqualIID(iid, IID_IUnknown)) { *ppv = (IADsClass FAR * ) this; } else if (IsEqualIID(iid, IID_IDispatch)) { *ppv = (IADs FAR *) this; } else if (IsEqualIID(iid, IID_IADs)) { *ppv = (IADs FAR *) this; } else if (IsEqualIID(iid, IID_IADsClass)) { *ppv = (IADsClass FAR *) this; } else { *ppv = NULL; return E_NOINTERFACE; }
AddRef(); return NOERROR; }
/* IADs methods */
STDMETHODIMP CIISClass::SetInfo(THIS) { HRESULT hr = S_OK;
if (GetObjectState() == ADS_OBJECT_UNBOUND) {
hr = IISCreateObject(); BAIL_ON_FAILURE(hr);
//
// If the create succeeded, set the object type to bound
//
SetObjectState(ADS_OBJECT_BOUND);
}
hr = IISSetObject(); BAIL_ON_FAILURE(hr);
error:
RRETURN(hr); }
/* INTRINSA suppress=null_pointers, uninitialized */ HRESULT CIISClass::IISSetObject() { HRESULT hr = S_OK; METADATA_HANDLE hObjHandle = NULL; PMETADATA_RECORD pMetaDataArray = NULL; DWORD dwMDNumDataEntries = 0; CLASSINFO ClassInfo; LPBYTE pBuffer = NULL; CCredentials localCred;
memset(&ClassInfo, 0, sizeof(CLASSINFO));
//
// Add SetObject functionality : sophiac
//
if (GetObjectState() == ADS_OBJECT_UNBOUND) { hr = E_ADS_OBJECT_UNBOUND; BAIL_ON_FAILURE(hr); }
hr = OpenAdminBaseKey( localCred, _pszServerName, SCHEMA_CLASS_METABASE_PATH, METADATA_PERMISSION_WRITE, &_pAdminBase, &hObjHandle ); BAIL_ON_FAILURE(hr);
hr = MakeStringFromVariantArray(&_vMandatoryProperties, (LPBYTE*)&pBuffer); BAIL_ON_FAILURE(hr); hr = ValidateProperties((LPWSTR)pBuffer, TRUE); BAIL_ON_FAILURE(hr); hr = CheckDuplicateNames((LPWSTR)pBuffer); BAIL_ON_FAILURE(hr); ClassInfo.bstrMandatoryProperties = (BSTR)pBuffer;
pBuffer = NULL; hr = MakeStringFromVariantArray(&_vOptionalProperties, (LPBYTE*)&pBuffer); BAIL_ON_FAILURE(hr); hr = ValidateProperties((LPWSTR)pBuffer, FALSE); BAIL_ON_FAILURE(hr); hr = CheckDuplicateNames((LPWSTR)pBuffer); BAIL_ON_FAILURE(hr); ClassInfo.bstrOptionalProperties = (BSTR)pBuffer;
pBuffer = NULL; hr = MakeStringFromVariantArray(&_vContainment, (LPBYTE*)&pBuffer); BAIL_ON_FAILURE(hr); hr = ValidateClassNames((LPWSTR)pBuffer); BAIL_ON_FAILURE(hr); hr = CheckDuplicateNames((LPWSTR)pBuffer); BAIL_ON_FAILURE(hr); ClassInfo.bstrContainment = (BSTR)pBuffer;
pBuffer = NULL; ClassInfo.fContainer = _fContainer;
//
// validate data
//
if ((ClassInfo.fContainer && !ClassInfo.bstrContainment) || (!ClassInfo.fContainer && ClassInfo.bstrContainment) ) { hr = E_ADS_SCHEMA_VIOLATION; BAIL_ON_FAILURE(hr); }
// Things are okay, so reset the _v members just incase things have changed
hr = MakeVariantFromStringList( ClassInfo.bstrMandatoryProperties, &(_vMandatoryProperties)); BAIL_ON_FAILURE(hr); hr = MakeVariantFromStringList( ClassInfo.bstrOptionalProperties, &(_vOptionalProperties)); BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringList( ClassInfo.bstrContainment, &(_vContainment)); BAIL_ON_FAILURE(hr);
hr = IISMarshallClassProperties( &ClassInfo, &pMetaDataArray, &dwMDNumDataEntries ); BAIL_ON_FAILURE(hr);
hr = MetaBaseSetAllData( _pAdminBase, hObjHandle, _pszClassName, (PMETADATA_RECORD)pMetaDataArray, dwMDNumDataEntries ); BAIL_ON_FAILURE(hr);
//
// update schema cache
//
_pSchema->SetClassInfo(_pszClassName, &ClassInfo); BAIL_ON_FAILURE(hr);
_bExistClass = TRUE;
error:
//
// if failed to create properties for new class, delete class node
//
if (FAILED(hr) && !_bExistClass && hObjHandle) {
MetaBaseDeleteObject( _pAdminBase, hObjHandle, (LPWSTR)_pszClassName ); }
if (ClassInfo.bstrOptionalProperties) { FreeADsMem(ClassInfo.bstrOptionalProperties); }
if (ClassInfo.bstrMandatoryProperties) { FreeADsMem(ClassInfo.bstrMandatoryProperties); }
if (ClassInfo.bstrContainment) { FreeADsMem(ClassInfo.bstrContainment); }
if (pBuffer) { FreeADsMem(pBuffer); }
if (pMetaDataArray) { FreeADsMem(pMetaDataArray); }
if (_pAdminBase && hObjHandle) { CloseAdminBaseKey(_pAdminBase, hObjHandle); }
RRETURN(hr); }
HRESULT CIISClass::IISCreateObject() { HRESULT hr = S_OK; METADATA_HANDLE hObjHandle = NULL; CCredentials localCred;
//
// Add CreateObject functionality : sophiac
//
hr = OpenAdminBaseKey( localCred, _pszServerName, SCHEMA_CLASS_METABASE_PATH, METADATA_PERMISSION_WRITE, &_pAdminBase, &hObjHandle ); BAIL_ON_FAILURE(hr);
//
// Pass in full path
//
hr = MetaBaseCreateObject( _pAdminBase, hObjHandle, _pszClassName ); BAIL_ON_FAILURE(hr);
error:
if (_pAdminBase && hObjHandle) { CloseAdminBaseKey(_pAdminBase, hObjHandle); }
RRETURN(hr); }
STDMETHODIMP CIISClass::GetInfo(THIS) { HRESULT hr = S_OK; PCLASSINFO pClassInfo = NULL;
//
// free up memory first
//
VariantClear( &_vMandatoryProperties ); VariantClear( &_vOptionalProperties ); VariantClear( &_vContainment );
//
// get classinfo from schema cache
//
pClassInfo = _pSchema->GetClassInfo(_pszClassName);
if (pClassInfo) { _fContainer = (VARIANT_BOOL)pClassInfo->fContainer; hr = MakeVariantFromStringList( pClassInfo->bstrMandatoryProperties, &_vMandatoryProperties); BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringList( pClassInfo->bstrOptionalProperties, &_vOptionalProperties); BAIL_ON_FAILURE(hr);
hr = MakeVariantFromStringList( pClassInfo->bstrContainment, &_vContainment); BAIL_ON_FAILURE(hr);
}
error:
RRETURN(hr); }
/* IADsClass methods */
STDMETHODIMP CIISClass::Get( THIS_ BSTR bstrName, VARIANT FAR* pvProp ) { HRESULT hr = S_OK; DWORD dwSyntaxId; DWORD dwID;
//
// check if property is a supported property
//
hr = ValidateClassObjProps(bstrName, &dwSyntaxId, &dwID); BAIL_ON_FAILURE(hr);
switch(dwID) { case CLASS_OPT_PROPERTIES: hr = get_OptionalProperties(pvProp); break; case CLASS_CONTAINMENT: hr = get_Containment(pvProp); break; case CLASS_CONTAINER: pvProp->vt = VT_BOOL; pvProp->boolVal = _fContainer? VARIANT_TRUE : VARIANT_FALSE; break; default: hr = E_ADS_PROPERTY_NOT_SUPPORTED; }
error:
RRETURN(hr); }
HRESULT CIISClass::Put( THIS_ BSTR bstrName, VARIANT vProp ) { HRESULT hr = S_OK; DWORD dwSyntaxId = 0; DWORD dwID;
VARIANT vVar;
//
// check if property is a supported property and
// loop up its syntax id
//
hr = ValidateClassObjProps(bstrName, &dwSyntaxId, &dwID); BAIL_ON_FAILURE(hr);
VariantInit(&vVar); hr = VariantCopyInd(&vVar, &vProp); BAIL_ON_FAILURE(hr);
//
// update both classinfo and member variables
//
switch(dwID) { case CLASS_OPT_PROPERTIES: if (vVar.vt != VT_EMPTY && !((V_VT(&vVar) & VT_VARIANT) && V_ISARRAY(&vVar))) { hr = E_ADS_CANT_CONVERT_DATATYPE; BAIL_ON_FAILURE(hr); } hr = VariantCopy(&_vOptionalProperties, &vVar); BAIL_ON_FAILURE(hr); break;
case CLASS_CONTAINMENT: if (vVar.vt != VT_EMPTY && !((V_VT(&vVar) & VT_VARIANT) && V_ISARRAY(&vVar))) { hr = E_ADS_CANT_CONVERT_DATATYPE; BAIL_ON_FAILURE(hr); } hr = VariantCopy(&_vContainment, &vVar); BAIL_ON_FAILURE(hr); break;
case CLASS_CONTAINER: hr = CheckVariantDataType(&vProp, VT_BOOL); BAIL_ON_FAILURE(hr); _fContainer = (vProp.boolVal == VARIANT_TRUE) ? true : false; break;
default: hr = E_ADS_PROPERTY_NOT_SUPPORTED; }
error:
VariantClear(&vVar);
RRETURN(hr); }
STDMETHODIMP CIISClass::GetEx( THIS_ BSTR bstrName, VARIANT FAR* pvProp ) { HRESULT hr = S_OK;
//
// Get and GetEx are the same for class schema object
//
hr = Get(bstrName, pvProp); RRETURN(hr); }
STDMETHODIMP CIISClass::PutEx( THIS_ long lnControlCode, BSTR bstrName, VARIANT vProp ) { RRETURN(E_NOTIMPL); }
HRESULT CIISClass::ValidateProperties( LPWSTR pszList, BOOL bMandatory ) { WCHAR *pszNewList; WCHAR szName[MAX_PATH]; LPWSTR ObjectList = (LPWSTR)pszList; HRESULT hr;
if (pszList == NULL) RRETURN(S_OK);
// need to allocate +2 = 1 for null, 1 for extra comma
pszNewList = new WCHAR[wcslen(pszList)+2];
if (pszNewList == NULL) RRETURN(E_OUTOFMEMORY);
wcscpy(pszNewList, L"");
while ((ObjectList = grabProp(szName, ObjectList)) != NULL) { if (*szName != L'\0') { hr = _pSchema->ValidatePropertyName(szName); if (hr == E_ADS_PROPERTY_NOT_SUPPORTED) { hr = PropertyInMetabase(szName, bMandatory); } else {
// form the new list
wcscat(pszNewList, szName); wcscat(pszNewList, L","); }
BAIL_ON_FAILURE(hr); // if it's a legit bad name
} }
// get rid of the last comma
pszNewList[wcslen(pszNewList) - 1] = 0;
wcscpy(pszList, pszNewList);
delete [] pszNewList; RRETURN(S_OK);
error:
//
// return E_ADS_SCHEMA_VIOLATION if property not found in global list
//
delete [] pszNewList; RRETURN(E_ADS_SCHEMA_VIOLATION); }
HRESULT CIISClass::PropertyInMetabase( LPWSTR szPropName, BOOL bMandatory ) { // Oops - somethings wrong. What do we do? Depends...
//
// Check to see if the bad property name exists in the associated list
// in the metabase.
//
// If so (case 1), then we are trying to SetInfo after having deleted a property from
// the schema - so just silently remove the name from metabase & the cached class.
//
// If not (case 2), we are trying to SetInfo w/ a bogus property name,
// so throw an exception.
HRESULT hr = E_ADS_PROPERTY_NOT_SUPPORTED; CLASSINFO *pClassInfo; LPWSTR ObjectList; WCHAR szTestProp[MAX_PATH];
pClassInfo = _pSchema->GetClassInfo(_pszClassName);
if (pClassInfo == NULL) { RRETURN(hr); }
if (bMandatory == TRUE) { ObjectList = pClassInfo->bstrMandatoryProperties; } else { ObjectList = pClassInfo->bstrOptionalProperties; }
while ((ObjectList = grabProp(szTestProp, ObjectList)) != NULL) { if (wcscmp(szTestProp, szPropName) == 0) { hr = S_OK; // clear the error - we'll fix it (case 1)
} }
RRETURN(hr); }
HRESULT CIISClass::ValidateClassNames( LPWSTR pszList ) { WCHAR szName[MAX_PATH]; LPWSTR ObjectList = (LPWSTR)pszList; HRESULT hr;
while ((ObjectList = grabProp(szName, ObjectList)) != NULL) { if (*szName != L'\0') { hr = _pSchema->ValidateClassName(szName); if (FAILED(hr)) { if (_wcsicmp(szName, _pszClassName)) { BAIL_ON_FAILURE(hr); } } }
}
RRETURN(S_OK);
error:
//
// return E_ADS_SCHEMA_VIOLATION if classname not found in global list
//
RRETURN(E_ADS_SCHEMA_VIOLATION); }
STDMETHODIMP CIISClass::get_PrimaryInterface( THIS_ BSTR FAR *pbstrGUID ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::get_CLSID( THIS_ BSTR FAR *pbstrCLSID ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::put_CLSID( THIS_ BSTR bstrCLSID ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::get_OID( THIS_ BSTR FAR *pbstrOID ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::put_OID( THIS_ BSTR bstrOID ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::get_Abstract( THIS_ VARIANT_BOOL FAR *pfAbstract ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::put_Abstract( THIS_ VARIANT_BOOL fAbstract ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::get_Auxiliary( THIS_ VARIANT_BOOL FAR *pfAuxiliary) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::put_Auxiliary( THIS_ VARIANT_BOOL fAuxiliary ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::get_NamingProperties( THIS_ VARIANT FAR *retval ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::put_NamingProperties( THIS_ VARIANT vNamingProperties ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::get_MandatoryProperties( THIS_ VARIANT FAR *retval ) { if ( !retval ) RRETURN(E_ADS_BAD_PARAMETER);
VariantInit( retval );
RRETURN(VariantCopy(retval, &_vMandatoryProperties)); }
STDMETHODIMP CIISClass::put_MandatoryProperties( THIS_ VARIANT vMandatoryProperties ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::get_OptionalProperties( THIS_ VARIANT FAR *retval ) { if ( !retval ) RRETURN(E_ADS_BAD_PARAMETER);
VariantInit( retval );
RRETURN(VariantCopy(retval, &_vOptionalProperties)); }
STDMETHODIMP CIISClass::put_OptionalProperties( THIS_ VARIANT vOptionalProperties ) { HRESULT hr = put_VARIANT_Property( this, TEXT("OptionalProperties"), vOptionalProperties );
if ( hr == E_ADS_CANT_CONVERT_DATATYPE ) { hr = E_NOTIMPL; }
RRETURN(hr); }
STDMETHODIMP CIISClass::get_DerivedFrom( THIS_ VARIANT FAR *pvDerivedFrom ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::put_DerivedFrom( THIS_ VARIANT vDerivedFrom ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::get_AuxDerivedFrom( THIS_ VARIANT FAR *pvAuxDerivedFrom ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::put_AuxDerivedFrom( THIS_ VARIANT vAuxDerivedFrom ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::get_PossibleSuperiors( THIS_ VARIANT FAR *pvPossSuperiors ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::put_PossibleSuperiors( THIS_ VARIANT vPossSuperiors ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::get_Containment( THIS_ VARIANT FAR *pvContainment ) { if ( !pvContainment ) RRETURN(E_ADS_BAD_PARAMETER); VariantInit( pvContainment ); RRETURN( VariantCopy( pvContainment, &_vContainment )); }
STDMETHODIMP CIISClass::put_Containment( THIS_ VARIANT vContainment ) { HRESULT hr = put_VARIANT_Property( this, TEXT("Containment"), vContainment );
if ( hr == E_ADS_CANT_CONVERT_DATATYPE ) { hr = E_NOTIMPL; }
RRETURN(hr); }
STDMETHODIMP CIISClass::get_Container( THIS_ VARIANT_BOOL FAR *pfContainer ) { if ( !pfContainer ) RRETURN(E_ADS_BAD_PARAMETER);
*pfContainer = _fContainer? VARIANT_TRUE : VARIANT_FALSE; RRETURN(S_OK); }
STDMETHODIMP CIISClass::put_Container( THIS_ VARIANT_BOOL fContainer ) { HRESULT hr = put_VARIANT_BOOL_Property( this, TEXT("Container"), fContainer ); RRETURN(hr); }
STDMETHODIMP CIISClass::get_HelpFileName( THIS_ BSTR FAR *pbstrHelpFileName ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::put_HelpFileName( THIS_ BSTR bstrHelpFile ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::get_HelpFileContext( THIS_ long FAR *plHelpContext ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::put_HelpFileContext( THIS_ long lHelpContext ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISClass::Qualifiers(THIS_ IADsCollection FAR* FAR* ppQualifiers) { RRETURN(E_NOTIMPL); }
HRESULT CIISClass::AllocateClassObject(CIISClass FAR * FAR * ppClass) {
CIISClass FAR *pClass = NULL; CAggregatorDispMgr FAR *pDispMgr = NULL; CPropertyCache FAR * pPropertyCache = NULL; HRESULT hr = S_OK;
pClass = new CIISClass(); if ( pClass == 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 *) pClass, DISPID_REGULAR ); BAIL_ON_FAILURE(hr);
hr = pDispMgr->LoadTypeInfoEntry( LIBID_ADs, IID_IADsClass, (IADsClass *) pClass, DISPID_REGULAR ); BAIL_ON_FAILURE(hr);
pClass->_pDispMgr = pDispMgr; *ppClass = pClass;
RRETURN(hr);
error:
delete pDispMgr; delete pClass;
RRETURN(hr);
}
/******************************************************************/ /* Class CIISProperty
/******************************************************************/
DEFINE_IDispatch_Implementation(CIISProperty) DEFINE_IADs_Implementation(CIISProperty)
CIISProperty::CIISProperty() : _pDispMgr( NULL ), _bstrOID( NULL ), _bstrSyntax( NULL ), _lMaxRange( 0 ), _lMinRange( 0 ), _fMultiValued( FALSE ), _lMetaId( 0 ), _lUserType(IIS_MD_UT_SERVER ), _lAllAttributes( 0), _dwSyntaxId( IIS_SYNTAX_ID_DWORD ), _dwFlags( PROP_RW ), _dwMask( 0 ), _dwPropID( 0 ), _bExistProp(FALSE), _pSchema(NULL), _pszServerName(NULL), _pszPropName(NULL), _pAdminBase(NULL) {
VariantInit(&_vDefault);
ADsAllocString(L"Integer", &_bstrSyntax); ENLIST_TRACKING(CIISProperty); }
CIISProperty::~CIISProperty() { if ( _bstrOID ) { ADsFreeString( _bstrOID ); }
if ( _bstrSyntax ) { ADsFreeString( _bstrSyntax ); }
if (_pszServerName) { FreeADsStr(_pszServerName); }
if (_pszPropName) { FreeADsStr(_pszPropName); }
VariantClear( &_vDefault ); delete _pDispMgr; }
/* #pragma INTRINSA suppress=all */ HRESULT CIISProperty::CreateProperty( BSTR bstrParent, BSTR bstrRelative, DWORD dwObjectState, REFIID riid, void **ppvObj ) { CIISProperty FAR * pProperty = NULL; HRESULT hr = S_OK; CCredentials localCred; PROPERTYINFO *pPropertyInfo; OBJECTINFO ObjectInfo; POBJECTINFO pObjectInfo = NULL; CLexer Lexer(bstrParent);
hr = AllocatePropertyObject( &pProperty ); BAIL_ON_FAILURE(hr);
pObjectInfo = &ObjectInfo; memset(pObjectInfo, 0, sizeof(OBJECTINFO));
hr = ADsObject(&Lexer, pObjectInfo); BAIL_ON_FAILURE(hr);
hr = InitServerInfo(localCred, pObjectInfo->TreeName, &pProperty->_pAdminBase, &pProperty->_pSchema); BAIL_ON_FAILURE(hr);
pProperty->_pszServerName = AllocADsStr(pObjectInfo->TreeName);
if (!pProperty->_pszServerName) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
pProperty->_pszPropName = AllocADsStr(bstrRelative);
if (!pProperty->_pszPropName) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
pPropertyInfo = pProperty->_pSchema->GetPropertyInfo(bstrRelative);
if (pPropertyInfo) {
LPWSTR pszSyntax;
pProperty->_bExistProp = TRUE; hr = ADsAllocString( pPropertyInfo->bstrOID, &pProperty->_bstrOID); BAIL_ON_FAILURE(hr);
pProperty->_lMaxRange = pPropertyInfo->lMaxRange; pProperty->_lMinRange = pPropertyInfo->lMinRange; pProperty->_fMultiValued = (VARIANT_BOOL)pPropertyInfo->fMultiValued;
pProperty->_lMetaId = pPropertyInfo->dwMetaID; pProperty->_lUserType = pPropertyInfo->dwUserGroup; pProperty->_lAllAttributes = pPropertyInfo->dwMetaFlags; pProperty->_dwSyntaxId = pPropertyInfo->dwSyntaxId; pProperty->_dwFlags = pPropertyInfo->dwFlags; pProperty->_dwMask = pPropertyInfo->dwMask; pProperty->_dwPropID = pPropertyInfo->dwPropID;
pszSyntax = SyntaxIdToString(pProperty->_dwSyntaxId); hr = ADsAllocString(pszSyntax, &(pProperty->_bstrSyntax)); BAIL_ON_FAILURE(hr);
if (pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_DWORD || pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_IPSECLIST || pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_NTACL || pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_BINARY ) { (pProperty->_vDefault).vt = VT_I4; (pProperty->_vDefault).lVal = pPropertyInfo->dwDefault; } else if (pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_BOOL || pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK) { (pProperty->_vDefault).vt = VT_BOOL; (pProperty->_vDefault).boolVal = pPropertyInfo->dwDefault ? VARIANT_TRUE : VARIANT_FALSE; } else if (pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_MULTISZ || pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_MIMEMAP ) { LPWSTR pszStr = pPropertyInfo->szDefault;
hr = MakeVariantFromStringArray(NULL, pszStr, &(pProperty->_vDefault)); BAIL_ON_FAILURE(hr); } else { (pProperty->_vDefault).vt = VT_BSTR; hr = ADsAllocString( pPropertyInfo->szDefault, &(pProperty->_vDefault.bstrVal)); BAIL_ON_FAILURE(hr); } }
hr = pProperty->InitializeCoreObject( bstrParent, bstrRelative, PROPERTY_CLASS_NAME, NO_SCHEMA, CLSID_IISProperty, dwObjectState ); BAIL_ON_FAILURE(hr);
hr = pProperty->QueryInterface( riid, ppvObj ); BAIL_ON_FAILURE(hr);
pProperty->Release();
FreeObjectInfo(pObjectInfo);
RRETURN(hr);
error:
*ppvObj = NULL;
delete pProperty;
FreeObjectInfo(pObjectInfo);
RRETURN(hr); }
STDMETHODIMP CIISProperty::QueryInterface(REFIID iid, LPVOID FAR* ppv) { if (IsEqualIID(iid, IID_IUnknown)) { *ppv = (IADsProperty FAR *) this; } else if (IsEqualIID(iid, IID_IDispatch)) { *ppv = (IADs FAR *) this; } else if (IsEqualIID(iid, IID_IADs)) { *ppv = (IADs FAR *) this; } else if (IsEqualIID(iid, IID_IISSchemaObject)) { *ppv = (IISSchemaObject FAR *) this; } else if (IsEqualIID(iid, IID_IADsProperty)) { *ppv = (IADsProperty FAR *) this; } else { *ppv = NULL; return E_NOINTERFACE; }
AddRef(); return NOERROR; }
/* IADs methods */
STDMETHODIMP CIISProperty::SetInfo(THIS) { HRESULT hr = S_OK;
if (GetObjectState() == ADS_OBJECT_UNBOUND) {
//
// fill in all unset fields
//
// User set an explicit the MetaID for a new object
// we need to validate it.
if( _lMetaId != 0 && !IsMetaIdAvailable( _lMetaId ) ) { return E_ADS_SCHEMA_VIOLATION; }
if (!_bstrSyntax) { LPWSTR pszSyntax; pszSyntax = SyntaxIdToString(_dwSyntaxId); hr = ADsAllocString(pszSyntax, &_bstrSyntax); BAIL_ON_FAILURE(hr); }
//
// If the create succeded, set the object type to bound
//
SetObjectState(ADS_OBJECT_BOUND);
}
hr = IISSetObject(); BAIL_ON_FAILURE(hr);
error:
RRETURN(hr); }
HRESULT CIISProperty::IISSetObject() { HRESULT hr = S_OK; METADATA_HANDLE hObjHandle = NULL; METADATA_RECORD mdr; PropValue pv; CCredentials localCred; PROPERTYINFO PropertyInfo;
memset(&PropertyInfo, 0, sizeof(PROPERTYINFO));
//
// Add SetObject functionality : sophiac
//
if (GetObjectState() == ADS_OBJECT_UNBOUND) { hr = E_ADS_OBJECT_UNBOUND; BAIL_ON_FAILURE(hr); }
//
// validate data
//
switch(_dwSyntaxId) { case IIS_SYNTAX_ID_DWORD: if (_vDefault.vt != VT_EMPTY) { hr = CheckVariantDataType(&_vDefault, VT_I4); if (FAILED(hr)) { hr = E_ADS_SCHEMA_VIOLATION; } BAIL_ON_FAILURE(hr); } if (_lMaxRange < _lMinRange) { hr = E_ADS_SCHEMA_VIOLATION; BAIL_ON_FAILURE(hr); } break;
case IIS_SYNTAX_ID_BOOL: case IIS_SYNTAX_ID_BOOL_BITMASK: if ((_vDefault.vt != VT_EMPTY && _vDefault.vt != VT_BOOL) || _lMaxRange != 0 || _lMinRange != 0 ) { hr = E_ADS_SCHEMA_VIOLATION; BAIL_ON_FAILURE(hr); } break;
case IIS_SYNTAX_ID_STRING: case IIS_SYNTAX_ID_EXPANDSZ: if ((_vDefault.vt != VT_EMPTY && _vDefault.vt != VT_BSTR) || _lMaxRange != 0 || _lMinRange != 0 ) { hr = E_ADS_SCHEMA_VIOLATION; BAIL_ON_FAILURE(hr); } break;
case IIS_SYNTAX_ID_MIMEMAP: case IIS_SYNTAX_ID_MULTISZ: if ((_vDefault.vt != VT_EMPTY && _vDefault.vt != VT_VARIANT && !((V_VT(&_vDefault) & VT_VARIANT) && V_ISARRAY(&_vDefault))) || _lMaxRange != 0 || _lMinRange != 0 ) { hr = E_ADS_SCHEMA_VIOLATION; BAIL_ON_FAILURE(hr); } break;
case IIS_SYNTAX_ID_IPSECLIST: if (_vDefault.vt != VT_EMPTY || _lMaxRange != 0 || _lMinRange != 0 ) { hr = E_ADS_SCHEMA_VIOLATION; BAIL_ON_FAILURE(hr); } break;
case IIS_SYNTAX_ID_BINARY: case IIS_SYNTAX_ID_NTACL: if (_vDefault.vt != VT_EMPTY || _lMaxRange != 0 || _lMinRange != 0 ) { hr = E_ADS_SCHEMA_VIOLATION; BAIL_ON_FAILURE(hr); } break;
default: break;
}
//
// set property Default values
//
PropertyInfo.lMaxRange = _lMaxRange; PropertyInfo.lMinRange = _lMinRange; PropertyInfo.fMultiValued = _fMultiValued; PropertyInfo.dwFlags = _dwFlags; PropertyInfo.dwSyntaxId = _dwSyntaxId; PropertyInfo.dwMask = _dwMask; PropertyInfo.dwMetaFlags = _lAllAttributes; PropertyInfo.dwUserGroup = _lUserType;
hr = ConvertDefaultValue(&_vDefault, &PropertyInfo); BAIL_ON_FAILURE(hr);
hr = SetMetaID(); BAIL_ON_FAILURE(hr);
PropertyInfo.dwMetaID = _lMetaId; PropertyInfo.dwPropID = _dwPropID;
hr = OpenAdminBaseKey( localCred, _pszServerName, SCHEMA_PROP_METABASE_PATH, METADATA_PERMISSION_WRITE, &_pAdminBase, &hObjHandle ); BAIL_ON_FAILURE(hr);
//
// set property name under Properties/Names
//
MD_SET_DATA_RECORD(&mdr, (DWORD)_lMetaId, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, ((DWORD)wcslen((LPWSTR)_pszPropName)+1)*2, (unsigned char *)_pszPropName);
hr = _pAdminBase->SetData(hObjHandle, L"Names", &mdr); BAIL_ON_FAILURE(hr);
//
// set property attributes/types under Properties/Types
//
InitPropValue(&pv, &PropertyInfo); mdr.dwMDDataType = BINARY_METADATA; mdr.dwMDDataLen = sizeof(PropValue); mdr.pbMDData = (unsigned char *)&pv; hr = _pAdminBase->SetData(hObjHandle, L"Types", &mdr); BAIL_ON_FAILURE(hr);
DataForSyntaxID(&PropertyInfo, &mdr); hr = _pAdminBase->SetData(hObjHandle, L"Defaults", &mdr); BAIL_ON_FAILURE(hr);
//
// update schema cache
//
hr = _pSchema->SetPropertyInfo(_pszPropName, &PropertyInfo); BAIL_ON_FAILURE(hr);
_bExistProp = TRUE;
error:
if (PropertyInfo.szDefault) { if (PropertyInfo.dwSyntaxId == IIS_SYNTAX_ID_STRING || PropertyInfo.dwSyntaxId == IIS_SYNTAX_ID_EXPANDSZ) { FreeADsStr(PropertyInfo.szDefault ); } else if (PropertyInfo.dwSyntaxId == IIS_SYNTAX_ID_MULTISZ) { FreeADsMem(PropertyInfo.szDefault ); } }
//
// if validation failed and new prop, delete class node
//
if (FAILED(hr) && !_bExistProp && hObjHandle) {
_pAdminBase->DeleteData( hObjHandle, (LPWSTR)L"Names", _lMetaId, ALL_METADATA ); _pAdminBase->DeleteData( hObjHandle, (LPWSTR)L"Types", _lMetaId, ALL_METADATA ); _pAdminBase->DeleteData( hObjHandle, (LPWSTR)L"Defaults", _lMetaId, ALL_METADATA ); }
if (_pAdminBase && hObjHandle) { CloseAdminBaseKey(_pAdminBase, hObjHandle); }
RRETURN(hr); }
STDMETHODIMP CIISProperty::GetInfo(THIS) { HRESULT hr = S_OK; PROPERTYINFO *pPropertyInfo = NULL;
//
// free up memory first
//
VariantClear( &_vDefault );
if ( _bstrOID ) { ADsFreeString( _bstrOID ); }
if ( _bstrSyntax ) { ADsFreeString( _bstrSyntax ); }
pPropertyInfo = _pSchema->GetPropertyInfo(_pszPropName);
if (pPropertyInfo) {
hr = ADsAllocString( pPropertyInfo->bstrOID, &_bstrOID); BAIL_ON_FAILURE(hr);
hr = ADsAllocString( pPropertyInfo->bstrSyntax, &_bstrSyntax); BAIL_ON_FAILURE(hr);
_lMaxRange = pPropertyInfo->lMaxRange; _lMinRange = pPropertyInfo->lMinRange; _fMultiValued = (VARIANT_BOOL)pPropertyInfo->fMultiValued;
_lMetaId = pPropertyInfo->dwMetaID; _lUserType = pPropertyInfo->dwUserGroup; _lAllAttributes = pPropertyInfo->dwMetaFlags; _dwSyntaxId = pPropertyInfo->dwSyntaxId; _dwFlags = pPropertyInfo->dwFlags; _dwMask = pPropertyInfo->dwMask; _dwPropID = pPropertyInfo->dwPropID;
if (pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_DWORD || pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_IPSECLIST || pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_NTACL || pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_BINARY ) { _vDefault.vt = VT_I4; _vDefault.lVal = pPropertyInfo->dwDefault; } else if (pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_BOOL || pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK) { _vDefault.vt = VT_BOOL; _vDefault.boolVal = pPropertyInfo->dwDefault ? VARIANT_TRUE : VARIANT_FALSE; } else if (pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_MULTISZ || pPropertyInfo->dwSyntaxId == IIS_SYNTAX_ID_MIMEMAP ) { LPWSTR pszStr = pPropertyInfo->szDefault;
hr = MakeVariantFromStringArray(NULL, pszStr, &_vDefault); BAIL_ON_FAILURE(hr); } else { _vDefault.vt = VT_BSTR; hr = ADsAllocString( pPropertyInfo->szDefault, &(_vDefault.bstrVal)); BAIL_ON_FAILURE(hr); } }
error:
RRETURN(hr); }
STDMETHODIMP CIISProperty::Get( THIS_ BSTR bstrName, VARIANT FAR* pvProp ) { HRESULT hr = S_OK; DWORD dwSyntaxId; DWORD dwID;
//
// check if property is a supported property
//
hr = ValidatePropertyObjProps(bstrName, &dwSyntaxId, &dwID); BAIL_ON_FAILURE(hr);
switch(dwID) { case PROP_SYNTAX: pvProp->vt = VT_BSTR; hr = ADsAllocString( _bstrSyntax, &pvProp->bstrVal); break;
case PROP_MAXRANGE: pvProp->vt = VT_I4; pvProp->lVal = _lMaxRange; break;
case PROP_MINRANGE: pvProp->vt = VT_I4; pvProp->lVal = _lMinRange; break;
case PROP_MULTIVALUED: pvProp->vt = VT_BOOL; pvProp->boolVal = _fMultiValued? VARIANT_TRUE : VARIANT_FALSE; break;
case PROP_PROPNAME: pvProp->vt = VT_BSTR; hr = ADsAllocString( _pszPropName, &pvProp->bstrVal); break;
case PROP_METAID: if (_lMetaId == 0) { hr = E_ADS_PROPERTY_NOT_SET; } else { pvProp->vt = VT_I4; pvProp->lVal = _lMetaId; } break;
case PROP_USERTYPE: pvProp->vt = VT_I4; pvProp->lVal = _lUserType; break;
case PROP_ALLATTRIBUTES: pvProp->vt = VT_I4; pvProp->lVal = _lAllAttributes; break;
case PROP_INHERIT: pvProp->vt = VT_BOOL; pvProp->boolVal = _lAllAttributes & METADATA_INHERIT ? VARIANT_TRUE : VARIANT_FALSE; break;
case PROP_SECURE: pvProp->vt = VT_BOOL; pvProp->boolVal = _lAllAttributes & METADATA_SECURE ? VARIANT_TRUE : VARIANT_FALSE; break;
case PROP_REFERENCE: pvProp->vt = VT_BOOL; pvProp->boolVal = _lAllAttributes & METADATA_REFERENCE ? VARIANT_TRUE : VARIANT_FALSE; break;
case PROP_VOLATILE: pvProp->vt = VT_BOOL; pvProp->boolVal = _lAllAttributes & METADATA_VOLATILE ? VARIANT_TRUE : VARIANT_FALSE; break;
case PROP_INSERTPATH: pvProp->vt = VT_BOOL; pvProp->boolVal = _lAllAttributes & METADATA_INSERT_PATH ? VARIANT_TRUE : VARIANT_FALSE; break;
case PROP_DEFAULT: hr = VariantCopy(pvProp, &_vDefault); BAIL_ON_FAILURE(hr); break;
default: hr = E_ADS_PROPERTY_NOT_SUPPORTED; }
error:
RRETURN(hr); }
HRESULT CIISProperty::Put( THIS_ BSTR bstrName, VARIANT vProp ) { HRESULT hr = S_OK; DWORD dwSyntaxId = 0; DWORD dwID; VARIANT vVar;
//
// check if property is a supported property
//
hr = ValidatePropertyObjProps(bstrName, &dwSyntaxId, &dwID); BAIL_ON_FAILURE(hr);
switch(dwID) { case PROP_SYNTAX: if (_bExistProp) { hr = E_ADS_SCHEMA_VIOLATION; BAIL_ON_FAILURE(hr); }
hr = ValidateSyntaxName(vProp.bstrVal, &dwSyntaxId); BAIL_ON_FAILURE(hr); hr = ADsReAllocString( &_bstrSyntax, vProp.bstrVal ? vProp.bstrVal: TEXT("") ); BAIL_ON_FAILURE(hr); _dwSyntaxId = dwSyntaxId; if (_dwSyntaxId == IIS_SYNTAX_ID_MIMEMAP || _dwSyntaxId == IIS_SYNTAX_ID_MULTISZ) { _fMultiValued = VARIANT_TRUE; }
break;
case PROP_MAXRANGE: hr = CheckVariantDataType(&vProp, VT_I4); BAIL_ON_FAILURE(hr); _lMaxRange = vProp.lVal; break;
case PROP_MINRANGE: hr = CheckVariantDataType(&vProp, VT_I4); BAIL_ON_FAILURE(hr); _lMinRange = vProp.lVal; break;
case PROP_USERTYPE: hr = CheckVariantDataType(&vProp, VT_I4); BAIL_ON_FAILURE(hr); _lUserType = vProp.lVal; break;
case PROP_INHERIT: hr = CheckVariantDataType(&vProp, VT_BOOL); BAIL_ON_FAILURE(hr); if (vProp.boolVal == VARIANT_TRUE) { _lAllAttributes |= METADATA_INHERIT; } else { _lAllAttributes &= ~METADATA_INHERIT; } break;
case PROP_PARTIALPATH: hr = CheckVariantDataType(&vProp, VT_BOOL); BAIL_ON_FAILURE(hr); if (vProp.boolVal == VARIANT_TRUE) { _lAllAttributes |= METADATA_PARTIAL_PATH; } else { _lAllAttributes &= ~METADATA_PARTIAL_PATH; } break;
case PROP_SECURE: hr = CheckVariantDataType(&vProp, VT_BOOL); BAIL_ON_FAILURE(hr); if (vProp.boolVal == VARIANT_TRUE) { _lAllAttributes |= METADATA_SECURE; } else { _lAllAttributes &= ~METADATA_SECURE; } break;
case PROP_REFERENCE: hr = CheckVariantDataType(&vProp, VT_BOOL); BAIL_ON_FAILURE(hr); if (vProp.boolVal == VARIANT_TRUE) { _lAllAttributes |= METADATA_REFERENCE; } else { _lAllAttributes &= ~METADATA_REFERENCE; } break;
case PROP_VOLATILE: hr = CheckVariantDataType(&vProp, VT_BOOL); BAIL_ON_FAILURE(hr); if (vProp.boolVal == VARIANT_TRUE) { _lAllAttributes |= METADATA_VOLATILE; } else { _lAllAttributes &= ~METADATA_VOLATILE; } break;
case PROP_ISINHERIT: hr = CheckVariantDataType(&vProp, VT_BOOL); BAIL_ON_FAILURE(hr); if (vProp.boolVal == VARIANT_TRUE) { _lAllAttributes |= METADATA_ISINHERITED; } else { _lAllAttributes &= ~METADATA_ISINHERITED; } break;
case PROP_INSERTPATH: hr = CheckVariantDataType(&vProp, VT_BOOL); BAIL_ON_FAILURE(hr); if (vProp.boolVal == VARIANT_TRUE) { _lAllAttributes |= METADATA_INSERT_PATH; } else { _lAllAttributes &= ~METADATA_INSERT_PATH; } break;
case PROP_DEFAULT: VariantInit(&vVar); hr = VariantCopyInd(&vVar, &vProp); BAIL_ON_FAILURE(hr);
VariantClear( &_vDefault ); _vDefault = vVar; break;
case PROP_METAID: hr = CheckVariantDataType(&vProp, VT_I4); BAIL_ON_FAILURE(hr); hr = put_MetaId( vProp.lVal ); break;
default: hr = E_ADS_PROPERTY_NOT_SUPPORTED; }
error:
RRETURN(hr); }
STDMETHODIMP CIISProperty::GetEx( THIS_ BSTR bstrName, VARIANT FAR* pvProp ) { HRESULT hr = S_OK;
//
// Get and GetEx are the same for property schema object
//
hr = Get(bstrName, pvProp); RRETURN(hr); }
STDMETHODIMP CIISProperty::PutEx( THIS_ long lnControlCode, BSTR bstrName, VARIANT vProp ) { RRETURN(E_NOTIMPL); }
HRESULT CIISProperty::ConvertDefaultValue( PVARIANT pVar, PROPERTYINFO *pPropInfo ) { HRESULT hr = S_OK; LPBYTE *pBuffer;
if (pVar->vt != VT_EMPTY) { if (pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_DWORD || pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_IPSECLIST || pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_NTACL || pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_BINARY ) { pPropInfo->dwDefault = (DWORD)pVar->lVal; } else if (pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_BOOL || pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_BOOL_BITMASK) { pPropInfo->dwDefault = pVar->boolVal ? 1 : 0; } else if (pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_MULTISZ || pPropInfo->dwSyntaxId == IIS_SYNTAX_ID_MIMEMAP ) { hr = MakeMultiStringFromVariantArray(pVar, (LPBYTE*)&pBuffer); BAIL_ON_FAILURE(hr); pPropInfo->szDefault = (LPWSTR) pBuffer; } else { if (pVar->vt == VT_BSTR && pVar->bstrVal && *(pVar->bstrVal)) { pPropInfo->szDefault = AllocADsStr(pVar->bstrVal); if (!pPropInfo->szDefault) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); } } } }
error:
RRETURN(hr); }
HRESULT CIISProperty::ValidateSyntaxName( LPWSTR pszName, PDWORD pdwSyntax ) { HRESULT hr = S_OK; DWORD i;
//
// Look for the given syntax name
//
for ( i = 0; i < g_cIISSyntax; i++ ) { if ( _wcsicmp( g_aIISSyntax[i].bstrName, pszName ) == 0 ) { *pdwSyntax = g_aIISSyntax[i].dwIISSyntaxId; RRETURN(S_OK); } }
RRETURN(E_ADS_BAD_PARAMETER); }
/* IADsProperty methods */
STDMETHODIMP CIISProperty::get_OID( THIS_ BSTR FAR *pbstrOID ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISProperty::put_OID( THIS_ BSTR bstrOID ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISProperty::get_Syntax( THIS_ BSTR FAR *pbstrSyntax ) { if ( !pbstrSyntax ) RRETURN(E_ADS_BAD_PARAMETER);
RRETURN( ADsAllocString( _bstrSyntax, pbstrSyntax ));
}
STDMETHODIMP CIISProperty::put_Syntax( THIS_ BSTR bstrSyntax ) { HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
if (SUCCEEDED(hr_check)) { RRETURN(E_FAIL); }
HRESULT hr; DWORD dwSyntaxId;
if (_bExistProp) { RRETURN(E_ADS_SCHEMA_VIOLATION); }
hr = ValidateSyntaxName(bstrSyntax, &dwSyntaxId); BAIL_ON_FAILURE(hr);
hr = ADsReAllocString( &_bstrSyntax, bstrSyntax); BAIL_ON_FAILURE(hr); _dwSyntaxId = dwSyntaxId;
if (_dwSyntaxId == IIS_SYNTAX_ID_MIMEMAP || _dwSyntaxId == IIS_SYNTAX_ID_MULTISZ) { _fMultiValued = VARIANT_TRUE; }
error:
RRETURN(hr); }
STDMETHODIMP CIISProperty::get_MaxRange( THIS_ long FAR *plMaxRange ) { if ( !plMaxRange ) RRETURN(E_ADS_BAD_PARAMETER);
*plMaxRange = _lMaxRange; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::put_MaxRange( THIS_ long lMaxRange ) { HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
if (SUCCEEDED(hr_check)) { RRETURN(E_FAIL); }
_lMaxRange = lMaxRange; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::get_MinRange( THIS_ long FAR *plMinRange ) { if ( !plMinRange ) RRETURN(E_ADS_BAD_PARAMETER);
*plMinRange = _lMinRange; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::put_MinRange( THIS_ long lMinRange ) { HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
if (SUCCEEDED(hr_check)) { RRETURN(E_FAIL); }
_lMinRange = lMinRange; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::get_MultiValued( THIS_ VARIANT_BOOL FAR *pfMultiValued ) { if ( !pfMultiValued ) RRETURN(E_ADS_BAD_PARAMETER);
*pfMultiValued = _fMultiValued; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::put_MultiValued( THIS_ VARIANT_BOOL fMultiValued ) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISProperty::Qualifiers(THIS_ IADsCollection FAR* FAR* ppQualifiers) { RRETURN(E_NOTIMPL); }
HRESULT CIISProperty::AllocatePropertyObject(CIISProperty FAR * FAR * ppProperty) { CIISProperty FAR *pProperty = NULL; CPropertyCache FAR * pPropertyCache = NULL; CAggregatorDispMgr FAR *pDispMgr = NULL; HRESULT hr = S_OK;
pProperty = new CIISProperty(); if ( pProperty == 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 *) pProperty, DISPID_REGULAR ); BAIL_ON_FAILURE(hr);
hr = pDispMgr->LoadTypeInfoEntry( LIBID_ADs, IID_IADsProperty, (IADsProperty *) pProperty, DISPID_REGULAR ); BAIL_ON_FAILURE(hr);
hr = pDispMgr->LoadTypeInfoEntry( LIBID_IISOle, IID_IISPropertyAttribute, (IISPropertyAttribute *)pProperty, DISPID_REGULAR ); BAIL_ON_FAILURE(hr);
pProperty->_pDispMgr = pDispMgr; *ppProperty = pProperty;
RRETURN(hr);
error:
delete pDispMgr; delete pProperty;
RRETURN(hr);
}
STDMETHODIMP CIISProperty::get_PropName(THIS_ BSTR FAR * retval) { HRESULT hr = S_OK;
hr = ADsAllocString((LPWSTR)_pszPropName, retval); RRETURN(hr); }
STDMETHODIMP CIISProperty::get_MetaId(THIS_ LONG FAR * retval) { HRESULT hr = S_OK;
if (_lMetaId == 0) { hr = E_ADS_PROPERTY_NOT_SET; } else { *retval = _lMetaId; }
RRETURN(hr); }
STDMETHODIMP CIISProperty::put_MetaId(THIS_ LONG lMetaId) { if (GetObjectState() != ADS_OBJECT_UNBOUND) { // Only valid for unsaved objects
RRETURN( E_ADS_OBJECT_EXISTS ); } if( lMetaId < 0 ) { // Never a valid metabase id
RRETURN( E_ADS_BAD_PARAMETER ); } if( !IsMetaIdAvailable( (DWORD)lMetaId ) ) { // This id is already in use
RRETURN( E_ADS_SCHEMA_VIOLATION ); }
_lMetaId = (DWORD)lMetaId; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::get_UserType(THIS_ LONG FAR * retval) { *retval = _lUserType; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::put_UserType(THIS_ LONG lUserType) { HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
if (SUCCEEDED(hr_check)) { RRETURN(E_FAIL); }
_lUserType = (DWORD)lUserType; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::get_AllAttributes(THIS_ LONG FAR * retval) { *retval = _lAllAttributes; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::get_Inherit(THIS_ VARIANT_BOOL FAR * retval) { *retval = _lAllAttributes & METADATA_INHERIT ? VARIANT_TRUE : VARIANT_FALSE; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::put_Inherit(THIS_ VARIANT_BOOL bInherit) { HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
if (SUCCEEDED(hr_check)) { RRETURN(E_FAIL); }
if (bInherit == VARIANT_TRUE) { _lAllAttributes |= METADATA_INHERIT; } else { _lAllAttributes &= ~METADATA_INHERIT; } RRETURN(S_OK); }
STDMETHODIMP CIISProperty::get_PartialPath(THIS_ VARIANT_BOOL FAR * retval) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISProperty::put_PartialPath(THIS_ VARIANT_BOOL bPartialPath) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISProperty::get_Reference(THIS_ VARIANT_BOOL FAR * retval) { *retval = _lAllAttributes & METADATA_REFERENCE ? VARIANT_TRUE : VARIANT_FALSE; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::put_Reference(THIS_ VARIANT_BOOL bReference) { HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
if (SUCCEEDED(hr_check)) { RRETURN(E_FAIL); }
if (bReference == VARIANT_TRUE) { _lAllAttributes |= METADATA_REFERENCE; } else { _lAllAttributes &= ~METADATA_REFERENCE; } RRETURN(S_OK); }
STDMETHODIMP CIISProperty::get_Secure(THIS_ VARIANT_BOOL FAR * retval) { *retval = _lAllAttributes & METADATA_SECURE ? VARIANT_TRUE : VARIANT_FALSE; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::put_Secure(THIS_ VARIANT_BOOL bSecure) { HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
if (SUCCEEDED(hr_check)) { RRETURN(E_FAIL); }
if (bSecure == VARIANT_TRUE) { _lAllAttributes |= METADATA_SECURE; } else { _lAllAttributes &= ~METADATA_SECURE; } RRETURN(S_OK); }
STDMETHODIMP CIISProperty::get_Volatile(THIS_ VARIANT_BOOL FAR * retval) { *retval = _lAllAttributes & METADATA_VOLATILE ? VARIANT_TRUE : VARIANT_FALSE; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::put_Volatile(THIS_ VARIANT_BOOL bVolatile) { HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
if (SUCCEEDED(hr_check)) { RRETURN(E_FAIL); }
if (bVolatile == VARIANT_TRUE) { _lAllAttributes |= METADATA_VOLATILE; } else { _lAllAttributes &= ~METADATA_VOLATILE; } RRETURN(S_OK); }
STDMETHODIMP CIISProperty::get_Isinherit(THIS_ VARIANT_BOOL FAR * retval) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISProperty::put_Isinherit(THIS_ VARIANT_BOOL bIsinherit) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISProperty::get_InsertPath(THIS_ VARIANT_BOOL FAR * retval) { *retval = _lAllAttributes & METADATA_INSERT_PATH ? VARIANT_TRUE : VARIANT_FALSE; RRETURN(S_OK); }
STDMETHODIMP CIISProperty::put_InsertPath(THIS_ VARIANT_BOOL bInsertPath) { HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
if (SUCCEEDED(hr_check)) { RRETURN(E_FAIL); }
if (bInsertPath == VARIANT_TRUE) { _lAllAttributes |= METADATA_INSERT_PATH; } else { _lAllAttributes &= ~METADATA_INSERT_PATH; } RRETURN(S_OK); }
STDMETHODIMP CIISProperty::get_Default(THIS_ VARIANT FAR * retval) { VariantInit(retval); RRETURN(VariantCopy(retval, &_vDefault)); }
STDMETHODIMP CIISProperty::put_Default(THIS_ VARIANT vVarDefault) { HRESULT hr_check = _pSchema->ValidatePropertyName(_pszPropName);
if (SUCCEEDED(hr_check)) { RRETURN(E_FAIL); }
VariantClear(&_vDefault); RRETURN(VariantCopy(&_vDefault, &vVarDefault)); }
HRESULT CIISProperty::SetMetaID() { HRESULT hr = S_OK; DWORD dwMetaId;
//
// get metaid
//
if (_lMetaId == 0) { hr = _pSchema->LookupMetaID(_pszPropName, &dwMetaId);
//
// generate a meta id for this property
//
if (FAILED(hr)) {
hr = GenerateNewMetaID(_pszServerName, _pAdminBase, &dwMetaId); BAIL_ON_FAILURE(hr);
//
// since we don't support bit mask property for ext. schema,
// propid == metaid
//
_dwPropID = dwMetaId; } else { hr = _pSchema->LookupPropID(_pszPropName, &_dwPropID); ASSERT(hr); }
//
// assign new metaid to property
//
_lMetaId = (LONG)dwMetaId; }
error:
RRETURN(hr);
}
BOOL CIISProperty::IsMetaIdAvailable( DWORD MetaId ) /*++
Routine Description:
Determine if the ID is valid to set on a new property. The determinination is based on whether the id is not currently in use.
NOTE - We will not respect ranges of IDs reserved for the base object. Unless that value is already defined (per vanvan)
Arguments:
MetaId - The ID to validate
Return Value:
TRUE if the specified id is valid to set, FALSE otherwise --*/ { BOOL fRet = FALSE; HRESULT hr = NOERROR; CCredentials localCred; METADATA_HANDLE hObjHandle = NULL;
// Is the property specified by MetaId defined in the schema
hr = OpenAdminBaseKey( localCred, _pszServerName, SCHEMA_PROP_METABASE_PATH, METADATA_PERMISSION_READ, &_pAdminBase, &hObjHandle );
if( SUCCEEDED(hr) ) { METADATA_RECORD mdr; WCHAR wcsPropertyName[MAX_PATH + 1]; DWORD cb;
MD_SET_DATA_RECORD( &mdr, MetaId, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, STRING_METADATA, sizeof(wcsPropertyName), (unsigned char *)wcsPropertyName );
hr = _pAdminBase->GetData( hObjHandle, L"Names", &mdr, &cb );
if( MD_ERROR_DATA_NOT_FOUND == hr ) { fRet = TRUE; }
CloseAdminBaseKey(_pAdminBase, hObjHandle); }
return fRet; }
/******************************************************************/ /* Class CIISSyntax
/******************************************************************/
DEFINE_IDispatch_Implementation(CIISSyntax) DEFINE_IADs_Implementation(CIISSyntax) DEFINE_IADs_PutGetUnImplementation(CIISSyntax)
CIISSyntax::CIISSyntax() : _pSchema(NULL), _pDispMgr(NULL) { ENLIST_TRACKING(CIISSyntax); }
CIISSyntax::~CIISSyntax() { delete _pDispMgr; }
HRESULT CIISSyntax::CreateSyntax( BSTR bstrParent, SYNTAXINFO *pSyntaxInfo, DWORD dwObjectState, REFIID riid, void **ppvObj ) { CIISSyntax FAR *pSyntax = NULL; HRESULT hr = S_OK;
hr = AllocateSyntaxObject( &pSyntax ); BAIL_ON_FAILURE(hr);
hr = pSyntax->InitializeCoreObject( bstrParent, pSyntaxInfo->bstrName, SYNTAX_CLASS_NAME, NO_SCHEMA, CLSID_IISSyntax, dwObjectState ); BAIL_ON_FAILURE(hr);
pSyntax->_lOleAutoDataType = pSyntaxInfo->lOleAutoDataType;
hr = pSyntax->QueryInterface( riid, ppvObj ); BAIL_ON_FAILURE(hr);
pSyntax->Release();
RRETURN(hr);
error:
delete pSyntax; RRETURN(hr); }
STDMETHODIMP CIISSyntax::QueryInterface(REFIID iid, LPVOID FAR* ppv) { if (IsEqualIID(iid, IID_IUnknown)) { *ppv = (IADs FAR *) this; } else if (IsEqualIID(iid, IID_IDispatch)) { *ppv = (IADs FAR *) this; } else if (IsEqualIID(iid, IID_IADs)) { *ppv = (IADs FAR *) this; } else if (IsEqualIID(iid, IID_IADsSyntax)) { *ppv = (IADsSyntax FAR *) this; } else { *ppv = NULL; return E_NOINTERFACE; }
AddRef(); return NOERROR; }
/* IADs methods */
STDMETHODIMP CIISSyntax::SetInfo(THIS) { RRETURN(E_NOTIMPL); }
STDMETHODIMP CIISSyntax::GetInfo(THIS) { RRETURN(S_OK); }
HRESULT CIISSyntax::AllocateSyntaxObject(CIISSyntax FAR * FAR * ppSyntax) { CIISSyntax FAR *pSyntax = NULL; CAggregatorDispMgr FAR *pDispMgr = NULL; HRESULT hr = S_OK;
pSyntax = new CIISSyntax(); if ( pSyntax == NULL ) hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr);
pDispMgr = new CAggregatorDispMgr; if ( pDispMgr == NULL ) { hr = E_OUTOFMEMORY; if (pSyntax) { delete pSyntax; } } BAIL_ON_FAILURE(hr);
hr = pDispMgr->LoadTypeInfoEntry( LIBID_ADs, IID_IADsSyntax, (IADsSyntax *) pSyntax, DISPID_REGULAR ); BAIL_ON_FAILURE(hr);
pSyntax->_pDispMgr = pDispMgr; *ppSyntax = pSyntax;
RRETURN(hr);
error:
delete pDispMgr; delete pSyntax;
RRETURN(hr);
}
STDMETHODIMP CIISSyntax::get_OleAutoDataType( THIS_ long FAR *plOleAutoDataType ) { if ( !plOleAutoDataType ) RRETURN(E_ADS_BAD_PARAMETER);
*plOleAutoDataType = _lOleAutoDataType; RRETURN(S_OK); }
STDMETHODIMP CIISSyntax::put_OleAutoDataType( THIS_ long lOleAutoDataType ) { RRETURN(E_ADS_PROPERTY_NOT_SUPPORTED); }
/******************************************************************/ /* Misc Helpers
/******************************************************************/
HRESULT MakeVariantFromStringList( BSTR bstrList, VARIANT *pvVariant ) { HRESULT hr = S_OK; SAFEARRAY *aList = NULL; SAFEARRAYBOUND aBound; BSTR pszTempList = NULL;
if ( bstrList != NULL ) { // If bstrList is not null, then there we consider there
// to be one element
long nCount = 1;
long i = 0; TCHAR c; BSTR pszSrc;
hr = ADsAllocString( bstrList, &pszTempList ); BAIL_ON_FAILURE(hr);
c = pszTempList[i]; while ( c ) { if ( c == TEXT(',')) { pszTempList[i] = 0; nCount++; }
i++; c = pszTempList[i]; }
aBound.lLbound = 0; aBound.cElements = nCount;
aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
if ( aList == NULL ) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
pszSrc = pszTempList;
for ( i = 0; i < nCount; i++ ) { VARIANT v;
VariantInit(&v); V_VT(&v) = VT_BSTR;
hr = ADsAllocString( pszSrc, &(V_BSTR(&v))); BAIL_ON_FAILURE(hr);
hr = SafeArrayPutElement( aList, &i, &v ); VariantClear(&v); BAIL_ON_FAILURE(hr);
pszSrc += _tcslen( pszSrc ) + 1; }
VariantInit( pvVariant ); V_VT(pvVariant) = VT_ARRAY | VT_VARIANT; V_ARRAY(pvVariant) = aList;
ADsFreeString( pszTempList ); pszTempList = NULL;
} else { aBound.lLbound = 0; aBound.cElements = 0;
aList = SafeArrayCreate( VT_VARIANT, 1, &aBound );
if ( aList == NULL ) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
VariantInit( pvVariant ); V_VT(pvVariant) = VT_ARRAY | VT_VARIANT; V_ARRAY(pvVariant) = aList; }
RRETURN(S_OK);
error:
if ( pszTempList ) ADsFreeString( pszTempList );
if ( aList ) SafeArrayDestroy( aList );
RRETURN(hr); }
HRESULT ValidateClassObjProps( LPWSTR pszName, PDWORD pdwSyntax, PDWORD pdwID ) { DWORD i;
//
// Look for the given syntax name
//
for ( i = 0; i < g_cClassObjProps; i++ ) { if ( _wcsicmp( g_pClassObjProps[i].szObjectName, pszName) == 0 ) { *pdwSyntax = g_pClassObjProps[i].dwSyntaxId; *pdwID = g_pClassObjProps[i].dwID; RRETURN(S_OK); } }
RRETURN(E_ADS_BAD_PARAMETER);
}
HRESULT ValidatePropertyObjProps( LPWSTR pszName, PDWORD pdwSyntax, PDWORD pdwID ) { DWORD i;
//
// Look for the given syntax name
//
for ( i = 0; i < g_cPropertyObjProps; i++ ) { if ( _wcsicmp( g_pPropertyObjProps[i].szObjectName, pszName) == 0 ) { *pdwSyntax = g_pPropertyObjProps[i].dwSyntaxId; *pdwID = g_pPropertyObjProps[i].dwID; RRETURN(S_OK); } }
RRETURN(E_ADS_BAD_PARAMETER);
}
HRESULT IISMarshallClassProperties( CLASSINFO *pClassInfo, PMETADATA_RECORD * ppMetaDataRecords, PDWORD pdwMDNumDataEntries ) {
HRESULT hr = S_OK; PMETADATA_RECORD pMetaDataArray = NULL; static BOOL bTemp = FALSE;
//
// set to 4 because we're supporting 4 properties only
//
*pdwMDNumDataEntries = 4;
pMetaDataArray = (PMETADATA_RECORD) AllocADsMem( *pdwMDNumDataEntries * sizeof(METADATA_RECORD)); if (!pMetaDataArray ) { hr = E_OUTOFMEMORY; BAIL_ON_FAILURE(hr); }
*ppMetaDataRecords = pMetaDataArray;
//
// setting Containment and Container property for classes
//
pMetaDataArray->dwMDIdentifier = MD_SCHEMA_CLASS_CONTAINER; pMetaDataArray->dwMDAttributes = METADATA_NO_ATTRIBUTES; pMetaDataArray->dwMDUserType = IIS_MD_UT_SERVER; pMetaDataArray->dwMDDataType = DWORD_METADATA; pMetaDataArray->dwMDDataLen = sizeof(DWORD); if (pClassInfo) { pMetaDataArray->pbMDData = (unsigned char*)&(pClassInfo->fContainer); } else { pMetaDataArray->pbMDData = (BYTE*)&bTemp; } pMetaDataArray++;
pMetaDataArray->dwMDIdentifier = MD_SCHEMA_CLASS_CONTAINMENT; pMetaDataArray->dwMDAttributes = METADATA_NO_ATTRIBUTES; pMetaDataArray->dwMDUserType = IIS_MD_UT_SERVER; pMetaDataArray->dwMDDataType = STRING_METADATA; if (pClassInfo && pClassInfo->bstrContainment) { pMetaDataArray->dwMDDataLen = ((DWORD)wcslen((LPWSTR)pClassInfo->bstrContainment)+ 1)*2; pMetaDataArray->pbMDData = (unsigned char *)pClassInfo->bstrContainment; } else { pMetaDataArray->dwMDDataLen = 0; pMetaDataArray->pbMDData = NULL; }
pMetaDataArray++;
//
// setting Optional and Mandatory Properties
//
pMetaDataArray->dwMDIdentifier = MD_SCHEMA_CLASS_MAND_PROPERTIES; pMetaDataArray->dwMDAttributes = METADATA_NO_ATTRIBUTES; pMetaDataArray->dwMDUserType = IIS_MD_UT_SERVER; pMetaDataArray->dwMDDataType = STRING_METADATA; if (pClassInfo && pClassInfo->bstrMandatoryProperties) { pMetaDataArray->dwMDDataLen = ((DWORD)wcslen((LPWSTR)pClassInfo->bstrMandatoryProperties)+1)*2; pMetaDataArray->pbMDData = (unsigned char *)pClassInfo->bstrMandatoryProperties; } else { pMetaDataArray->dwMDDataLen = 0; pMetaDataArray->pbMDData = NULL; }
pMetaDataArray++;
pMetaDataArray->dwMDIdentifier = MD_SCHEMA_CLASS_OPT_PROPERTIES; pMetaDataArray->dwMDAttributes = METADATA_NO_ATTRIBUTES; pMetaDataArray->dwMDUserType = IIS_MD_UT_SERVER; pMetaDataArray->dwMDDataType = STRING_METADATA; if (pClassInfo && pClassInfo->bstrOptionalProperties) { pMetaDataArray->dwMDDataLen = ((DWORD)wcslen((LPWSTR)pClassInfo->bstrOptionalProperties)+1)*2; pMetaDataArray->pbMDData = (unsigned char *)pClassInfo->bstrOptionalProperties; } else { pMetaDataArray->dwMDDataLen = 0; pMetaDataArray->pbMDData = NULL; }
error:
RRETURN(hr); }
HRESULT GenerateNewMetaID( LPWSTR pszServerName, IMSAdminBase *pAdminBase, PDWORD pdwMetaID ) {
HRESULT hr = S_OK; DWORD dwMetaId = 0; METADATA_HANDLE hObjHandle = NULL; DWORD dwBufferSize = sizeof(DWORD); METADATA_RECORD mdrMDData; CCredentials localCred; LPBYTE pBuffer = (LPBYTE)&dwMetaId;
hr = OpenAdminBaseKey( localCred, pszServerName, IIS_MD_ADSI_SCHEMA_PATH_W, METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE, &pAdminBase, &hObjHandle ); BAIL_ON_FAILURE(hr);
MD_SET_DATA_RECORD(&mdrMDData, MD_SCHEMA_METAID, METADATA_NO_ATTRIBUTES, IIS_MD_UT_SERVER, DWORD_METADATA, dwBufferSize, pBuffer);
hr = pAdminBase->GetData( hObjHandle, L"", &mdrMDData, &dwBufferSize ); BAIL_ON_FAILURE(hr);
*pdwMetaID = dwMetaId;
//
// increment metaid by 1 for next property
//
dwMetaId++;
hr = pAdminBase->SetData( hObjHandle, L"", &mdrMDData ); BAIL_ON_FAILURE(hr); error:
if (hObjHandle) { CloseAdminBaseKey(pAdminBase, hObjHandle); }
RRETURN(hr); }
HRESULT CheckDuplicateNames( LPWSTR pszNames ) { WCHAR szName[MAX_PATH]; WCHAR szName2[MAX_PATH]; LPWSTR ObjectList = (LPWSTR)pszNames; LPWSTR CheckList = (LPWSTR)pszNames; DWORD dwCount = 0;
if (ObjectList == NULL || (ObjectList != NULL && *ObjectList == NULL)) { RRETURN(S_OK); }
while ((ObjectList = grabProp(szName, ObjectList)) != NULL) { if (*szName != L'\0') { CheckList = pszNames; while ((CheckList = grabProp(szName2, CheckList)) != NULL) { if (*szName2 != L'\0') { if (!_wcsicmp(szName, szName2)) { dwCount++; } } } if (dwCount > 1) { RRETURN(E_ADS_BAD_PARAMETER); } dwCount = 0; } }
RRETURN(S_OK); }
|