Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

531 lines
16 KiB

  1. //
  2. // relation.cpp : Implementation of ClassRelationshipPage
  3. //
  4. // Jon Newman <[email protected]>
  5. // Copyright (c) Microsoft Corporation 1997
  6. //
  7. #include "stdafx.h"
  8. #include "macros.h"
  9. USE_HANDLE_MACROS("SCHMMGMT(relation.cpp)")
  10. #include "compdata.h"
  11. #include "schmutil.h"
  12. #include "relation.h"
  13. #include "select.h"
  14. const CDialogControlsInfo ctrls[] =
  15. {
  16. { IDC_CLASS_REL_AUX_CLASSES, g_AuxiliaryClass, FALSE },
  17. { IDC_CLASS_REL_AUX_ADD, g_AuxiliaryClass, FALSE },
  18. { IDC_CLASS_REL_SUPER_CLASSES, g_Superiors, FALSE },
  19. { IDC_CLASS_REL_SUPER_ADD, g_Superiors, FALSE },
  20. } ;
  21. const DWORD ClassRelationshipPage::help_map[] =
  22. {
  23. IDI_CLASS, NO_HELP,
  24. IDC_CLASS_REL_NAME_STATIC, NO_HELP,
  25. IDC_CLASS_REL_PARENT_EDIT, IDH_CLASS_REL_PARENT_EDIT,
  26. IDC_CLASS_REL_AUX_CLASSES, IDH_CLASS_REL_AUX_CLASSES,
  27. IDC_STATIC_SYSTEMONLY_AUXILIARY, NO_HELP,
  28. IDC_CLASS_REL_AUX_ADD, IDH_CLASS_REL_AUX_ADD,
  29. IDC_CLASS_REL_AUX_REMOVE, IDH_CLASS_REL_AUX_REMOVE,
  30. IDC_CLASS_REL_SUPER_CLASSES, IDH_CLASS_REL_SUPER_CLASSES,
  31. IDC_STATIC_SYSTEMONLY_SUPERIOR, NO_HELP,
  32. IDC_CLASS_REL_SUPER_ADD, IDH_CLASS_REL_SUPER_ADD,
  33. IDC_CLASS_REL_SUPER_REMOVE, IDH_CLASS_REL_SUPER_REMOVE,
  34. IDC_CLASS_REL_SYSCLASS_STATIC, NO_HELP,
  35. 0,0
  36. };
  37. ClassRelationshipPage::ClassRelationshipPage(
  38. ComponentData *pScope,
  39. LPDATAOBJECT lpDataObject ) :
  40. CPropertyPageAutoDelete(ClassRelationshipPage::IDD)
  41. , m_pIADsObject( NULL )
  42. , fSystemClass( FALSE )
  43. , m_pSchemaObject( NULL )
  44. , m_pScopeControl( pScope )
  45. , m_lpScopeDataObj( lpDataObject )
  46. {
  47. ASSERT( NULL != m_pScopeControl );
  48. ASSERT( NULL != lpDataObject );
  49. }
  50. ClassRelationshipPage::~ClassRelationshipPage()
  51. {
  52. if (NULL != m_pIADsObject)
  53. m_pIADsObject->Release();
  54. if (NULL != m_pSchemaObject) {
  55. m_pScopeControl->g_SchemaCache.ReleaseRef( m_pSchemaObject );
  56. }
  57. }
  58. void
  59. ClassRelationshipPage::Load(
  60. Cookie& CookieRef
  61. ) {
  62. //
  63. // Store the cookie object pointer.
  64. //
  65. m_pCookie = &CookieRef;
  66. return;
  67. }
  68. BOOL
  69. ClassRelationshipPage::OnInitDialog()
  70. {
  71. HRESULT hr = S_OK;
  72. ASSERT( NULL == m_pIADsObject && m_szAdsPath.IsEmpty() );
  73. //
  74. // Get the schema cache object and the actual ADS object.
  75. //
  76. m_pSchemaObject = m_pScopeControl->g_SchemaCache.LookupSchemaObjectByCN(
  77. m_pCookie->strSchemaObject,
  78. SCHMMGMT_CLASS );
  79. if ( m_pSchemaObject ) {
  80. m_pScopeControl->GetSchemaObjectPath( m_pSchemaObject->commonName, m_szAdsPath );
  81. if ( !m_szAdsPath.IsEmpty() ) {
  82. hr = SchemaOpenObject( (LPWSTR)(LPCWSTR)m_szAdsPath,
  83. IID_IADs,
  84. (void **)&m_pIADsObject );
  85. ASSERT( SUCCEEDED(hr) );
  86. }
  87. }
  88. //
  89. // If we have no ADS object, we should error out!
  90. //
  91. if ( !m_pIADsObject ) {
  92. DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_NO_SCHEMA_OBJECT );
  93. ASSERT(FALSE);
  94. return TRUE;
  95. }
  96. //
  97. // get the current values.
  98. //
  99. VARIANT AdsResult;
  100. VariantInit( &AdsResult );
  101. //
  102. // ObjectName
  103. //
  104. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  105. hr = m_pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_DisplayName),
  106. &AdsResult );
  107. if ( SUCCEEDED( hr ) ) {
  108. ASSERT( AdsResult.vt == VT_BSTR );
  109. ObjectName = AdsResult.bstrVal;
  110. VariantClear( &AdsResult );
  111. }
  112. //
  113. // Parent Class.
  114. //
  115. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  116. hr = m_pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_SubclassOf),
  117. &AdsResult );
  118. if ( SUCCEEDED( hr ) ) {
  119. ASSERT( AdsResult.vt == VT_BSTR );
  120. ParentClass = AdsResult.bstrVal;
  121. VariantClear( &AdsResult );
  122. }
  123. // NTRAID#NTBUG9-460503,460511-2001/09/10-lucios
  124. // Replaced SysClass Computation by Making the window visible
  125. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  126. hr = m_pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_SystemOnly),
  127. &AdsResult );
  128. if ( SUCCEEDED( hr ) ) {
  129. ASSERT( AdsResult.vt == VT_BOOL );
  130. fSystemClass = AdsResult.boolVal;
  131. if ( fSystemClass ) {
  132. ASSERT(GetDlgItem( IDC_CLASS_REL_SYSCLASS_STATIC ) != NULL);
  133. GetDlgItem( IDC_CLASS_REL_SYSCLASS_STATIC )->ShowWindow( SW_SHOW );
  134. }
  135. VariantClear( &AdsResult );
  136. }
  137. //
  138. // Determine the auxiliary classes
  139. //
  140. VARIANT varClasses;
  141. VariantInit( &varClasses );
  142. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  143. hr = m_pIADsObject->GetEx( CComBSTR(g_AuxiliaryClass), &varClasses );
  144. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  145. if( SUCCEEDED(hr) )
  146. {
  147. hr = VariantToStringList( varClasses, strlistAuxiliary );
  148. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  149. }
  150. VariantClear( &varClasses );
  151. hr = m_pIADsObject->GetEx( CComBSTR(g_SystemAuxiliaryClass), &varClasses );
  152. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  153. if( SUCCEEDED(hr) )
  154. {
  155. hr = VariantToStringList( varClasses, strlistSystemAuxiliary );
  156. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  157. }
  158. VariantClear( &varClasses );
  159. //
  160. // Determine the superior classes
  161. //
  162. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  163. hr = m_pIADsObject->GetEx( CComBSTR(g_Superiors), &varClasses );
  164. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  165. if( SUCCEEDED(hr) )
  166. {
  167. hr = VariantToStringList( varClasses, strlistSuperior );
  168. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  169. }
  170. VariantClear( &varClasses );
  171. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  172. hr = m_pIADsObject->GetEx( CComBSTR(g_SystemSuperiors), &varClasses );
  173. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  174. if( SUCCEEDED(hr) )
  175. {
  176. hr = VariantToStringList( varClasses, strlistSystemSuperior );
  177. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  178. }
  179. VariantClear( &varClasses );
  180. hr = DissableReadOnlyAttributes( this, m_pIADsObject, ctrls, sizeof(ctrls)/sizeof(ctrls[0]) );
  181. // NTRAID#NTBUG9-503619-2002/05/15-lucios
  182. hr = S_OK;
  183. // This calls must be done before DDX binding
  184. m_listboxAuxiliary.InitType( m_pScopeControl,
  185. SELECT_AUX_CLASSES,
  186. IDC_CLASS_REL_AUX_REMOVE,
  187. &strlistSystemAuxiliary,
  188. IDC_STATIC_SYSTEMONLY_AUXILIARY
  189. );
  190. m_listboxSuperior.InitType( m_pScopeControl,
  191. SELECT_CLASSES,
  192. IDC_CLASS_REL_SUPER_REMOVE,
  193. &strlistSystemSuperior,
  194. IDC_STATIC_SYSTEMONLY_SUPERIOR
  195. );
  196. CPropertyPage::OnInitDialog();
  197. return TRUE;
  198. }
  199. BOOL
  200. ClassRelationshipPage::OnSetActive()
  201. {
  202. // always enable the Apply button
  203. SetModified(TRUE);
  204. return TRUE;
  205. }
  206. void
  207. ClassRelationshipPage::DoDataExchange(
  208. CDataExchange *pDX
  209. ) {
  210. HRESULT hr = S_OK;
  211. CPropertyPage::DoDataExchange( pDX );
  212. //{{AFX_DATA_MAP(ClassRelationshipPage)
  213. DDX_Control(pDX, IDC_CLASS_REL_PARENT_EDIT, m_staticParent );
  214. DDX_Control(pDX, IDC_CLASS_REL_AUX_CLASSES, m_listboxAuxiliary);
  215. DDX_Control(pDX, IDC_CLASS_REL_SUPER_CLASSES, m_listboxSuperior);
  216. DDX_Text( pDX, IDC_CLASS_REL_NAME_STATIC, ObjectName );
  217. DDX_Text( pDX, IDC_CLASS_REL_PARENT_EDIT, ParentClass );
  218. //}}AFX_DATA_MAP
  219. if ( !pDX->m_bSaveAndValidate ) {
  220. //
  221. // Fill the auxiliary classes list box.
  222. //
  223. m_listboxAuxiliary.ResetContent();
  224. hr = InsertEditItems( m_listboxAuxiliary, strlistAuxiliary );
  225. ASSERT( SUCCEEDED(hr) );
  226. hr = InsertEditItems( m_listboxAuxiliary, strlistSystemAuxiliary );
  227. ASSERT( SUCCEEDED(hr) );
  228. //
  229. // Fill the possible superiors list box.
  230. //
  231. m_listboxSuperior.ResetContent();
  232. hr = InsertEditItems( m_listboxSuperior, strlistSuperior );
  233. ASSERT( SUCCEEDED(hr) );
  234. hr = InsertEditItems( m_listboxSuperior, strlistSystemSuperior );
  235. ASSERT( SUCCEEDED(hr) );
  236. m_listboxAuxiliary.OnSelChange();
  237. m_listboxSuperior.OnSelChange();
  238. } else {
  239. //
  240. // All changes that we save are tied to button control routines.
  241. //
  242. strlistAuxiliary.RemoveAll();
  243. hr = RetrieveEditItemsWithExclusions(
  244. m_listboxAuxiliary,
  245. strlistAuxiliary,
  246. &strlistSystemAuxiliary
  247. );
  248. ASSERT( SUCCEEDED(hr) );
  249. strlistSuperior.RemoveAll();
  250. hr = RetrieveEditItemsWithExclusions(
  251. m_listboxSuperior,
  252. strlistSuperior,
  253. &strlistSystemSuperior
  254. );
  255. ASSERT( SUCCEEDED(hr) );
  256. }
  257. }
  258. BEGIN_MESSAGE_MAP(ClassRelationshipPage, CPropertyPage)
  259. ON_BN_CLICKED(IDC_CLASS_REL_AUX_ADD, OnButtonAuxiliaryClassAdd)
  260. ON_BN_CLICKED(IDC_CLASS_REL_AUX_REMOVE, OnButtonAuxiliaryClassRemove)
  261. ON_BN_CLICKED(IDC_CLASS_REL_SUPER_ADD, OnButtonSuperiorClassAdd)
  262. ON_BN_CLICKED(IDC_CLASS_REL_SUPER_REMOVE, OnButtonSuperiorClassRemove)
  263. ON_LBN_SELCHANGE(IDC_CLASS_REL_AUX_CLASSES, OnAuxiliarySelChange)
  264. ON_LBN_SELCHANGE(IDC_CLASS_REL_SUPER_CLASSES, OnSuperiorSelChange)
  265. ON_MESSAGE(WM_HELP, OnHelp)
  266. ON_MESSAGE(WM_CONTEXTMENU, OnContextHelp)
  267. END_MESSAGE_MAP()
  268. BOOL
  269. ClassRelationshipPage::OnApply(
  270. )
  271. //
  272. // Revisions:
  273. // CoryWest - 10/1/97 - Changes new additions to be listed by oid.
  274. // Add cache freshening to improve performance.
  275. //
  276. {
  277. ASSERT( NULL != m_pIADsObject);
  278. HRESULT hr = S_OK;
  279. HRESULT flush_result;
  280. ListEntry *pNewList = NULL;
  281. BOOL fApplyAbort = FALSE; // stop later saves
  282. BOOL fApplyFailed = FALSE; // should not close the box
  283. if ( m_listboxAuxiliary.IsModified() )
  284. {
  285. //
  286. // Update the auxiliary classes
  287. //
  288. VARIANT AdsValue;
  289. VariantInit( &AdsValue );
  290. hr = StringListToVariant( AdsValue, strlistAuxiliary );
  291. // NTRAID#NTBUG9-543624-2002/02/15-dantra-Result of StringListToVariant being ignored resulting in call to IADs::PutEx with incorrect data
  292. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  293. if( SUCCEEDED( hr ) ) hr = m_pIADsObject->PutEx( ADS_PROPERTY_UPDATE, CComBSTR(g_AuxiliaryClass), AdsValue );
  294. VariantClear( &AdsValue );
  295. // NTRAID#NTBUG9-542354-2002/02/14-dantra-Errors returned by IADs::Put and PutEx are being masked.
  296. if ( SUCCEEDED( hr ) ) hr = m_pIADsObject->SetInfo();
  297. if ( SUCCEEDED( hr )) {
  298. //
  299. // Update the aux class list in the cache.
  300. //
  301. hr = StringListToColumnList( m_pScopeControl,
  302. strlistAuxiliary,
  303. &pNewList );
  304. if ( SUCCEEDED( hr )) {
  305. m_pScopeControl->g_SchemaCache.FreeColumnList(
  306. m_pSchemaObject->auxiliaryClass );
  307. m_pSchemaObject->auxiliaryClass = pNewList;
  308. //
  309. // Refresh the display!
  310. //
  311. m_pScopeControl->QueryConsole()->UpdateAllViews(
  312. m_lpScopeDataObj, SCHMMGMT_CLASS, SCHMMGMT_UPDATEVIEW_REFRESH );
  313. }
  314. //
  315. // Continue with the directory operation even if
  316. // we couldn't update the display.
  317. //
  318. hr = S_OK;
  319. } else {
  320. //
  321. // Flush the IADS property cache so future
  322. // operations won't fail because of this one.
  323. //
  324. IADsPropertyList *pPropertyList;
  325. flush_result = m_pIADsObject->QueryInterface(
  326. IID_IADsPropertyList,
  327. reinterpret_cast<void**>(&pPropertyList) );
  328. if ( SUCCEEDED( flush_result ) ) {
  329. pPropertyList->PurgePropertyList();
  330. pPropertyList->Release();
  331. }
  332. }
  333. }
  334. if ( SUCCEEDED(hr) && m_listboxSuperior.IsModified() )
  335. {
  336. //
  337. // Update the superior classes
  338. //
  339. VARIANT AdsValue;
  340. VariantInit( &AdsValue );
  341. hr = StringListToVariant( AdsValue, strlistSuperior );
  342. // NTRAID#NTBUG9-543624-2002/02/15-dantra-Result of StringListToVariant being ignored resulting in call to IADs::PutEx with incorrect data
  343. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  344. if( SUCCEEDED( hr ) ) hr = m_pIADsObject->PutEx( ADS_PROPERTY_UPDATE, CComBSTR(g_Superiors), AdsValue );
  345. VariantClear( &AdsValue );
  346. // NTRAID#NTBUG9-542354-2002/02/14-dantra-Errors returned by IADs::Put and PutEx are being masked.
  347. if ( SUCCEEDED( hr ) ) hr = m_pIADsObject->SetInfo();
  348. }
  349. if ( hr == ADS_EXTENDED_ERROR )
  350. {
  351. DoExtErrMsgBox();
  352. }
  353. else if ( FAILED(hr) )
  354. {
  355. if( ERROR_DS_UNWILLING_TO_PERFORM == HRESULT_CODE(hr) )
  356. {
  357. fApplyFailed = TRUE;
  358. DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_CHANGE_REJECT );
  359. }
  360. else
  361. {
  362. fApplyAbort = TRUE;
  363. DoErrMsgBox( ::GetActiveWindow(), TRUE, GetErrorMessage(hr,TRUE) );
  364. }
  365. }
  366. else
  367. {
  368. // page is no longer "dirty"
  369. m_listboxAuxiliary.SetModified( FALSE );
  370. m_listboxSuperior.SetModified( FALSE );
  371. // Update comboBox status
  372. OnAuxiliarySelChange();
  373. OnSuperiorSelChange();
  374. SetModified( FALSE );
  375. }
  376. return !fApplyAbort && !fApplyFailed ; // return TRUE if nothing happened
  377. }
  378. void ClassRelationshipPage::OnAuxiliarySelChange()
  379. {
  380. m_listboxAuxiliary.OnSelChange();
  381. }
  382. void ClassRelationshipPage::OnSuperiorSelChange()
  383. {
  384. m_listboxSuperior.OnSelChange();
  385. }
  386. void ClassRelationshipPage::OnButtonAuxiliaryClassRemove()
  387. {
  388. if( m_listboxAuxiliary.RemoveListBoxItem() )
  389. SetModified( TRUE );
  390. }
  391. void ClassRelationshipPage::OnButtonSuperiorClassRemove()
  392. {
  393. if( m_listboxSuperior.RemoveListBoxItem() )
  394. SetModified( TRUE );
  395. }
  396. void
  397. ClassRelationshipPage::OnButtonAuxiliaryClassAdd()
  398. {
  399. if( m_listboxAuxiliary.AddNewObjectToList() )
  400. SetModified( TRUE );
  401. }
  402. void
  403. ClassRelationshipPage::OnButtonSuperiorClassAdd()
  404. {
  405. if( m_listboxSuperior.AddNewObjectToList() )
  406. SetModified( TRUE );
  407. }