windows-nt/Source/XPSP1/NT/admin/snapin/schmmgmt/relation.cpp
2020-09-26 16:20:57 +08:00

539 lines
14 KiB
C++

//
// relation.cpp : Implementation of ClassRelationshipPage
//
// Jon Newman <jonn@microsoft.com>
// Copyright (c) Microsoft Corporation 1997
//
#include "stdafx.h"
#include "macros.h"
USE_HANDLE_MACROS("SCHMMGMT(relation.cpp)")
#include "compdata.h"
#include "schmutil.h"
#include "relation.h"
#include "select.h"
const CDialogControlsInfo ctrls[] =
{
{ IDC_CLASS_REL_AUX_CLASSES, g_AuxiliaryClass, FALSE },
{ IDC_CLASS_REL_AUX_ADD, g_AuxiliaryClass, FALSE },
{ IDC_CLASS_REL_SUPER_CLASSES, g_Superiors, FALSE },
{ IDC_CLASS_REL_SUPER_ADD, g_Superiors, FALSE },
} ;
const DWORD ClassRelationshipPage::help_map[] =
{
IDI_CLASS, NO_HELP,
IDC_CLASS_REL_NAME_STATIC, NO_HELP,
IDC_CLASS_REL_PARENT_EDIT, IDH_CLASS_REL_PARENT_EDIT,
IDC_CLASS_REL_AUX_CLASSES, IDH_CLASS_REL_AUX_CLASSES,
IDC_STATIC_SYSTEMONLY_AUXILIARY, NO_HELP,
IDC_CLASS_REL_AUX_ADD, IDH_CLASS_REL_AUX_ADD,
IDC_CLASS_REL_AUX_REMOVE, IDH_CLASS_REL_AUX_REMOVE,
IDC_CLASS_REL_SUPER_CLASSES, IDH_CLASS_REL_SUPER_CLASSES,
IDC_STATIC_SYSTEMONLY_SUPERIOR, NO_HELP,
IDC_CLASS_REL_SUPER_ADD, IDH_CLASS_REL_SUPER_ADD,
IDC_CLASS_REL_SUPER_REMOVE, IDH_CLASS_REL_SUPER_REMOVE,
IDC_CLASS_REL_SYSCLASS_STATIC, NO_HELP,
0,0
};
ClassRelationshipPage::ClassRelationshipPage(
ComponentData *pScope,
LPDATAOBJECT lpDataObject ) :
CPropertyPage(ClassRelationshipPage::IDD)
, m_pIADsObject( NULL )
, fSystemClass( FALSE )
, m_pSchemaObject( NULL )
, m_pScopeControl( pScope )
, m_lpScopeDataObj( lpDataObject )
{
ASSERT( NULL != m_pScopeControl );
ASSERT( NULL != lpDataObject );
}
ClassRelationshipPage::~ClassRelationshipPage()
{
if (NULL != m_pIADsObject)
m_pIADsObject->Release();
if (NULL != m_pSchemaObject) {
m_pScopeControl->g_SchemaCache.ReleaseRef( m_pSchemaObject );
}
}
void
ClassRelationshipPage::Load(
Cookie& CookieRef
) {
//
// Store the cookie object pointer.
//
m_pCookie = &CookieRef;
return;
}
BOOL
ClassRelationshipPage::OnInitDialog()
{
HRESULT hr = S_OK;
ASSERT( NULL == m_pIADsObject && m_szAdsPath.IsEmpty() );
//
// Get the schema cache object and the actual ADS object.
//
m_pSchemaObject = m_pScopeControl->g_SchemaCache.LookupSchemaObjectByCN(
m_pCookie->strSchemaObject,
SCHMMGMT_CLASS );
if ( m_pSchemaObject ) {
m_pScopeControl->GetSchemaObjectPath( m_pSchemaObject->commonName, m_szAdsPath );
if ( !m_szAdsPath.IsEmpty() ) {
hr = ADsGetObject( (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
//
hr = m_pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_DisplayName),
&AdsResult );
if ( SUCCEEDED( hr ) ) {
ASSERT( AdsResult.vt == VT_BSTR );
ObjectName = AdsResult.bstrVal;
VariantClear( &AdsResult );
}
//
// Parent Class.
//
hr = m_pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_SubclassOf),
&AdsResult );
if ( SUCCEEDED( hr ) ) {
ASSERT( AdsResult.vt == VT_BSTR );
ParentClass = AdsResult.bstrVal;
VariantClear( &AdsResult );
}
//
// SysClass
//
hr = m_pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_SystemOnly),
&AdsResult );
if ( SUCCEEDED( hr ) )
{
ASSERT( AdsResult.vt == VT_BOOL );
fSystemClass = AdsResult.boolVal;
if ( fSystemClass )
{
SysClassString = g_SysClassString;
}
else
{
SysClassString = L"";
}
VariantClear( &AdsResult );
}
else
{
SysClassString = L"";
}
//
// Determine the auxiliary classes
//
VARIANT varClasses;
VariantInit( &varClasses );
hr = m_pIADsObject->GetEx( g_AuxiliaryClass, &varClasses );
ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
if( SUCCEEDED(hr) )
{
hr = VariantToStringList( varClasses, strlistAuxiliary );
ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
}
VariantClear( &varClasses );
hr = m_pIADsObject->GetEx( g_SystemAuxiliaryClass, &varClasses );
ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
if( SUCCEEDED(hr) )
{
hr = VariantToStringList( varClasses, strlistSystemAuxiliary );
ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
}
VariantClear( &varClasses );
//
// Determine the superior classes
//
hr = m_pIADsObject->GetEx( g_Superiors, &varClasses );
ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
if( SUCCEEDED(hr) )
{
hr = VariantToStringList( varClasses, strlistSuperior );
ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
}
VariantClear( &varClasses );
hr = m_pIADsObject->GetEx( g_SystemSuperiors, &varClasses );
ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
if( SUCCEEDED(hr) )
{
hr = VariantToStringList( varClasses, strlistSystemSuperior );
ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
}
VariantClear( &varClasses );
hr = DissableReadOnlyAttributes( this, m_pIADsObject, ctrls, sizeof(ctrls)/sizeof(ctrls[0]) );
ASSERT( SUCCEEDED(hr) ); // shouldn't fail, but unimportant, so ignore error
// This calls must be done before DDX binding
m_listboxAuxiliary.InitType( m_pScopeControl,
SELECT_AUX_CLASSES,
IDC_CLASS_REL_AUX_REMOVE,
&strlistSystemAuxiliary,
IDC_STATIC_SYSTEMONLY_AUXILIARY
);
m_listboxSuperior.InitType( m_pScopeControl,
SELECT_CLASSES,
IDC_CLASS_REL_SUPER_REMOVE,
&strlistSystemSuperior,
IDC_STATIC_SYSTEMONLY_SUPERIOR
);
CPropertyPage::OnInitDialog();
return TRUE;
}
BOOL
ClassRelationshipPage::OnSetActive()
{
// always enable the Apply button
SetModified(TRUE);
return TRUE;
}
void
ClassRelationshipPage::DoDataExchange(
CDataExchange *pDX
) {
HRESULT hr = S_OK;
CPropertyPage::DoDataExchange( pDX );
//{{AFX_DATA_MAP(ClassRelationshipPage)
DDX_Control(pDX, IDC_CLASS_REL_PARENT_EDIT, m_staticParent );
DDX_Control(pDX, IDC_CLASS_REL_AUX_CLASSES, m_listboxAuxiliary);
DDX_Control(pDX, IDC_CLASS_REL_SUPER_CLASSES, m_listboxSuperior);
DDX_Text( pDX, IDC_CLASS_REL_NAME_STATIC, ObjectName );
DDX_Text( pDX, IDC_CLASS_REL_PARENT_EDIT, ParentClass );
DDX_Text( pDX, IDC_CLASS_REL_SYSCLASS_STATIC, SysClassString );
//}}AFX_DATA_MAP
if ( !pDX->m_bSaveAndValidate ) {
//
// Fill the auxiliary classes list box.
//
m_listboxAuxiliary.ResetContent();
hr = InsertEditItems( m_listboxAuxiliary, strlistAuxiliary );
ASSERT( SUCCEEDED(hr) );
hr = InsertEditItems( m_listboxAuxiliary, strlistSystemAuxiliary );
ASSERT( SUCCEEDED(hr) );
//
// Fill the possible superiors list box.
//
m_listboxSuperior.ResetContent();
hr = InsertEditItems( m_listboxSuperior, strlistSuperior );
ASSERT( SUCCEEDED(hr) );
hr = InsertEditItems( m_listboxSuperior, strlistSystemSuperior );
ASSERT( SUCCEEDED(hr) );
m_listboxAuxiliary.OnSelChange();
m_listboxSuperior.OnSelChange();
} else {
//
// All changes that we save are tied to button control routines.
//
strlistAuxiliary.RemoveAll();
hr = RetrieveEditItemsWithExclusions(
m_listboxAuxiliary,
strlistAuxiliary,
&strlistSystemAuxiliary
);
ASSERT( SUCCEEDED(hr) );
strlistSuperior.RemoveAll();
hr = RetrieveEditItemsWithExclusions(
m_listboxSuperior,
strlistSuperior,
&strlistSystemSuperior
);
ASSERT( SUCCEEDED(hr) );
}
}
BEGIN_MESSAGE_MAP(ClassRelationshipPage, CPropertyPage)
ON_BN_CLICKED(IDC_CLASS_REL_AUX_ADD, OnButtonAuxiliaryClassAdd)
ON_BN_CLICKED(IDC_CLASS_REL_AUX_REMOVE, OnButtonAuxiliaryClassRemove)
ON_BN_CLICKED(IDC_CLASS_REL_SUPER_ADD, OnButtonSuperiorClassAdd)
ON_BN_CLICKED(IDC_CLASS_REL_SUPER_REMOVE, OnButtonSuperiorClassRemove)
ON_LBN_SELCHANGE(IDC_CLASS_REL_AUX_CLASSES, OnAuxiliarySelChange)
ON_LBN_SELCHANGE(IDC_CLASS_REL_SUPER_CLASSES, OnSuperiorSelChange)
ON_MESSAGE(WM_HELP, OnHelp)
ON_MESSAGE(WM_CONTEXTMENU, OnContextHelp)
END_MESSAGE_MAP()
BOOL
ClassRelationshipPage::OnApply(
)
//
// Revisions:
// CoryWest - 10/1/97 - Changes new additions to be listed by oid.
// Add cache freshening to improve performance.
//
{
ASSERT( NULL != m_pIADsObject);
HRESULT hr = S_OK;
HRESULT flush_result;
ListEntry *pNewList = NULL;
BOOL fApplyAbort = FALSE; // stop later saves
BOOL fApplyFailed = FALSE; // should not close the box
if ( m_listboxAuxiliary.IsModified() )
{
//
// Update the auxiliary classes
//
VARIANT AdsValue;
VariantInit( &AdsValue );
hr = StringListToVariant( AdsValue, strlistAuxiliary );
ASSERT( SUCCEEDED(hr) );
hr = m_pIADsObject->PutEx( ADS_PROPERTY_UPDATE, g_AuxiliaryClass, AdsValue );
ASSERT( SUCCEEDED(hr) );
VariantClear( &AdsValue );
hr = m_pIADsObject->SetInfo();
if ( SUCCEEDED( hr )) {
//
// Update the aux class list in the cache.
//
hr = StringListToColumnList( m_pScopeControl,
strlistAuxiliary,
&pNewList );
if ( SUCCEEDED( hr )) {
m_pScopeControl->g_SchemaCache.FreeColumnList(
m_pSchemaObject->auxiliaryClass );
m_pSchemaObject->auxiliaryClass = pNewList;
//
// Refresh the display!
//
m_pScopeControl->QueryConsole()->UpdateAllViews(
m_lpScopeDataObj, SCHMMGMT_CLASS, SCHMMGMT_UPDATEVIEW_REFRESH );
}
//
// Continue with the directory operation even if
// we couldn't update the display.
//
hr = S_OK;
} else {
//
// Flush the IADS property cache so future
// operations won't fail because of this one.
//
IADsPropertyList *pPropertyList;
flush_result = m_pIADsObject->QueryInterface(
IID_IADsPropertyList,
reinterpret_cast<void**>(&pPropertyList) );
if ( SUCCEEDED( flush_result ) ) {
pPropertyList->PurgePropertyList();
pPropertyList->Release();
}
}
}
if ( SUCCEEDED(hr) && m_listboxSuperior.IsModified() )
{
//
// Update the superior classes
//
VARIANT AdsValue;
VariantInit( &AdsValue );
hr = StringListToVariant( AdsValue, strlistSuperior );
ASSERT( SUCCEEDED(hr) );
hr = m_pIADsObject->PutEx( ADS_PROPERTY_UPDATE, g_Superiors, AdsValue );
ASSERT( SUCCEEDED(hr) );
VariantClear( &AdsValue );
hr = m_pIADsObject->SetInfo();
}
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
{
// page is no longer "dirty"
m_listboxAuxiliary.SetModified( FALSE );
m_listboxSuperior.SetModified( FALSE );
// Update comboBox status
OnAuxiliarySelChange();
OnSuperiorSelChange();
SetModified( FALSE );
}
return !fApplyAbort && !fApplyFailed ; // return TRUE if nothing happened
}
void ClassRelationshipPage::OnAuxiliarySelChange()
{
m_listboxAuxiliary.OnSelChange();
}
void ClassRelationshipPage::OnSuperiorSelChange()
{
m_listboxSuperior.OnSelChange();
}
void ClassRelationshipPage::OnButtonAuxiliaryClassRemove()
{
if( m_listboxAuxiliary.RemoveListBoxItem() )
SetModified( TRUE );
}
void ClassRelationshipPage::OnButtonSuperiorClassRemove()
{
if( m_listboxSuperior.RemoveListBoxItem() )
SetModified( TRUE );
}
void
ClassRelationshipPage::OnButtonAuxiliaryClassAdd()
{
if( m_listboxAuxiliary.AddNewObjectToList() )
SetModified( TRUE );
}
void
ClassRelationshipPage::OnButtonSuperiorClassAdd()
{
if( m_listboxSuperior.AddNewObjectToList() )
SetModified( TRUE );
}