// // attrpage.cpp : Implementation of ClassAttributePage // // Jon Newman // Copyright (c) Microsoft Corporation 1997 // // templated from relation.cpp JonN 8/8/97 // #include "stdafx.h" #include "macros.h" USE_HANDLE_MACROS("SCHMMGMT(attrpage.cpp)") #include "compdata.h" #include "schmutil.h" #include "select.h" #include "attrpage.h" const CDialogControlsInfo ctrls[] = { // { IDC_CLASS_MMB_MANDATORY_ATTRIBUTES, g_MustContain, FALSE }, // { IDC_CLASS_MMB_OPTIONAL_ATTRIBUTES, g_MayContain, FALSE }, { IDC_CLASS_MMB_OPTIONAL_ADD, g_MayContain, FALSE }, { IDC_CLASS_MMB_OPTIONAL_REMOVE, g_MayContain, FALSE }, } ; const DWORD ClassAttributePage::help_map[] = { IDI_CLASS, NO_HELP, IDC_CLASS_MMB_NAME_STATIC, NO_HELP, IDC_CLASS_MMB_MANDATORY_ATTRIBUTES, IDH_CLASS_MMB_MANDATORY_ATTRIBUTES, IDC_CLASS_MMB_OPTIONAL_ATTRIBUTES, IDH_CLASS_MMB_OPTIONAL_ATTRIBUTES, IDC_CLASS_MMB_SYSCLASS_STATIC, NO_HELP, IDC_CLASS_MMB_OPTIONAL_ADD, IDH_CLASS_MMB_OPTIONAL_ADD, IDC_CLASS_MMB_OPTIONAL_REMOVE, IDH_CLASS_MMB_OPTIONAL_REMOVE, 0,0 }; ClassAttributePage::ClassAttributePage( ComponentData *pScope, LPDATAOBJECT lpDataObject ) : CPropertyPageAutoDelete(ClassAttributePage::IDD), m_pIADsObject( NULL ), fSystemClass( FALSE ), m_pSchemaObject( NULL ), pScopeControl( pScope ), lpScopeDataObj( lpDataObject ) { ASSERT(pScopeControl); ASSERT(lpDataObject); } ClassAttributePage::~ClassAttributePage() { if (NULL != m_pIADsObject) { m_pIADsObject->Release(); } if (NULL != m_pSchemaObject) { pScopeControl->g_SchemaCache.ReleaseRef( m_pSchemaObject ); } } void ClassAttributePage::Load( Cookie& CookieRef ) { // // Store the cookie object pointer. // m_pCookie = &CookieRef; return; } BOOL ClassAttributePage::OnSetActive() { // always enable the Apply button SetModified(TRUE); return TRUE; } BOOL ClassAttributePage::OnInitDialog() { HRESULT hr = S_OK; ASSERT( NULL == m_pIADsObject && m_szAdsPath.IsEmpty() ); // // Get the schema cache object and the actual ADS object. // m_pSchemaObject = pScopeControl->g_SchemaCache.LookupSchemaObjectByCN( (PCWSTR)m_pCookie->strSchemaObject, SCHMMGMT_CLASS ); if ( m_pSchemaObject ) { pScopeControl->GetSchemaObjectPath( m_pSchemaObject->commonName, m_szAdsPath ); if ( !m_szAdsPath.IsEmpty() ) { hr = SchemaOpenObject( (LPWSTR)(LPCWSTR)m_szAdsPath, IID_IADs, (void **)&m_pIADsObject ); ASSERT( SUCCEEDED(hr) ); } } // // If we have no ADS object, we should error out! // if ( !m_pIADsObject ) { DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_NO_SCHEMA_OBJECT ); ASSERT(FALSE); return TRUE; } // // get the current values. // VARIANT AdsResult; VariantInit( &AdsResult ); // // ObjectName // // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR hr = m_pIADsObject->Get( const_cast((LPCTSTR)g_DisplayName), &AdsResult ); if ( SUCCEEDED( hr ) ) { ASSERT( AdsResult.vt == VT_BSTR ); ObjectName = AdsResult.bstrVal; VariantClear( &AdsResult ); } // NTRAID#NTBUG9-460503,460511-2001/09/10-lucios // Replaced SysClass Computation by Making the window visible // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR hr = m_pIADsObject->Get( const_cast((LPCTSTR)g_SystemOnly), &AdsResult ); if ( SUCCEEDED( hr ) ) { ASSERT( AdsResult.vt == VT_BOOL ); fSystemClass = AdsResult.boolVal; if ( fSystemClass ) { ASSERT(GetDlgItem( IDC_CLASS_MMB_SYSCLASS_STATIC ) != NULL); GetDlgItem( IDC_CLASS_MMB_SYSCLASS_STATIC )->ShowWindow( SW_SHOW ); } VariantClear( &AdsResult ); } // // Determine the mandatory attributes // VARIANT varAttributes; VariantInit( &varAttributes ); // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR hr = m_pIADsObject->GetEx( CComBSTR(g_MustContain), &varAttributes ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); if( SUCCEEDED(hr) ) { hr = VariantToStringList( varAttributes, strlistMandatory ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); } VariantClear( &varAttributes ); // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR hr = m_pIADsObject->GetEx( CComBSTR(g_SystemMustContain), &varAttributes ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); if( SUCCEEDED(hr) ) { hr = VariantToStringList( varAttributes, strlistSystemMandatory ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); } VariantClear( &varAttributes ); // // Determine the optional attributes // // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR hr = m_pIADsObject->GetEx( CComBSTR(g_MayContain), &varAttributes ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); if( SUCCEEDED(hr) ) { hr = VariantToStringList( varAttributes, strlistOptional ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); } VariantClear( &varAttributes ); // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR hr = m_pIADsObject->GetEx( CComBSTR(g_SystemMayContain), &varAttributes ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); if( SUCCEEDED(hr) ) { hr = VariantToStringList( varAttributes, strlistSystemOptional ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); } VariantClear( &varAttributes ); hr = DissableReadOnlyAttributes( this, m_pIADsObject, ctrls, sizeof(ctrls)/sizeof(ctrls[0]) ); // NTRAID#NTBUG9-503619-2002/05/15-lucios hr = S_OK; // This call must be done before DDX binding m_listboxOptional.InitType( pScopeControl, SELECT_ATTRIBUTES, IDC_CLASS_MMB_OPTIONAL_REMOVE, &strlistSystemOptional ); CPropertyPage::OnInitDialog(); return TRUE; } void ClassAttributePage::DoDataExchange( CDataExchange *pDX ) { HRESULT hr = S_OK; CPropertyPage::DoDataExchange( pDX ); //{{AFX_DATA_MAP(ClassAttributePage) DDX_Control(pDX, IDC_CLASS_MMB_MANDATORY_ATTRIBUTES, m_listboxMandatory); DDX_Control(pDX, IDC_CLASS_MMB_OPTIONAL_ATTRIBUTES, m_listboxOptional); DDX_Text( pDX, IDC_CLASS_MMB_NAME_STATIC, ObjectName ); //}}AFX_DATA_MAP if ( !pDX->m_bSaveAndValidate ) { // // Fill the mandatory attributes list box. // m_listboxMandatory.ResetContent(); hr = InsertEditItems( m_listboxMandatory, strlistMandatory ); ASSERT( SUCCEEDED(hr) ); hr = InsertEditItems( m_listboxMandatory, strlistSystemMandatory ); ASSERT( SUCCEEDED(hr) ); // // Fill the possible optionals list box. // m_listboxOptional.ResetContent(); hr = InsertEditItems( m_listboxOptional, strlistOptional ); ASSERT( SUCCEEDED(hr) ); hr = InsertEditItems( m_listboxOptional, strlistSystemOptional ); ASSERT( SUCCEEDED(hr) ); m_listboxOptional.OnSelChange(); } else { // // All changes that we save are tied to button control routines. // strlistMandatory.RemoveAll(); hr = RetrieveEditItemsWithExclusions( m_listboxMandatory, strlistMandatory, &strlistSystemMandatory ); ASSERT( SUCCEEDED(hr) ); strlistOptional.RemoveAll(); hr = RetrieveEditItemsWithExclusions( m_listboxOptional, strlistOptional, &strlistSystemOptional ); ASSERT( SUCCEEDED(hr) ); } } BEGIN_MESSAGE_MAP(ClassAttributePage, CPropertyPage) ON_BN_CLICKED(IDC_CLASS_MMB_OPTIONAL_ADD, OnButtonOptionalAttributeAdd) ON_BN_CLICKED(IDC_CLASS_MMB_OPTIONAL_REMOVE, OnButtonOptionalAttributeRemove) ON_LBN_SELCHANGE(IDC_CLASS_MMB_OPTIONAL_ATTRIBUTES, OnOptionalSelChange) ON_MESSAGE(WM_HELP, OnHelp) ON_MESSAGE(WM_CONTEXTMENU, OnContextHelp) END_MESSAGE_MAP() BOOL ClassAttributePage::OnApply() { ASSERT( NULL != m_pIADsObject); ASSERT( NULL != m_pSchemaObject); HRESULT hr = S_OK; BOOL fApplyAbort = FALSE; // stop later saves BOOL fApplyFailed = FALSE; // should not close the box ListEntry *pNewList; if ( m_listboxOptional.IsModified() ) { // // Update the optional attributes // VARIANT AdsValue; VariantInit( &AdsValue ); hr = StringListToVariant( AdsValue, strlistOptional ); // NTRAID#NTBUG9-543624-2002/02/15-dantra-Result of StringListToVariant being ignored resulting in call to IADs::PutEx with incorrect data // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR if( SUCCEEDED( hr ) ) hr = m_pIADsObject->PutEx( ADS_PROPERTY_UPDATE, CComBSTR(g_MayContain), AdsValue ); VariantClear( &AdsValue ); // NTRAID#NTBUG9-542354-2002/02/14-dantra-Errors returned by IADs::Put and PutEx are being masked. if( SUCCEEDED( hr ) ) hr = m_pIADsObject->SetInfo(); if ( SUCCEEDED( hr )) { // // Update the cached data. // hr = StringListToColumnList( pScopeControl, strlistOptional, &pNewList ); if ( SUCCEEDED( hr )) { pScopeControl->g_SchemaCache.FreeColumnList( m_pSchemaObject->mayContain ); m_pSchemaObject->mayContain = pNewList; } // // Continue with the directory operation even if // we couldn't update the cache. // hr = S_OK; } } if ( hr == ADS_EXTENDED_ERROR ) { DoExtErrMsgBox(); } else if ( FAILED(hr) ) { if( ERROR_DS_UNWILLING_TO_PERFORM == HRESULT_CODE(hr) ) { fApplyFailed = TRUE; DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_CHANGE_REJECT ); } else { fApplyAbort = TRUE; DoErrMsgBox( ::GetActiveWindow(), TRUE, GetErrorMessage(hr,TRUE) ); } } else { m_listboxOptional.SetModified( FALSE ); SetModified( FALSE ); // // Refresh the display! // pScopeControl->QueryConsole()->UpdateAllViews( lpScopeDataObj, SCHMMGMT_CLASS, SCHMMGMT_UPDATEVIEW_REFRESH ); } return !fApplyAbort && !fApplyFailed ; // return TRUE if nothing happened } void ClassAttributePage::OnOptionalSelChange() { m_listboxOptional.OnSelChange(); } void ClassAttributePage::OnButtonOptionalAttributeRemove() { if( m_listboxOptional.RemoveListBoxItem() ) SetModified( TRUE ); } void ClassAttributePage::OnButtonOptionalAttributeAdd() { if( m_listboxOptional.AddNewObjectToList() ) SetModified( TRUE ); }