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.

447 lines
12 KiB

  1. //
  2. // attrpage.cpp : Implementation of ClassAttributePage
  3. //
  4. // Jon Newman <[email protected]>
  5. // Copyright (c) Microsoft Corporation 1997
  6. //
  7. // templated from relation.cpp JonN 8/8/97
  8. //
  9. #include "stdafx.h"
  10. #include "macros.h"
  11. USE_HANDLE_MACROS("SCHMMGMT(attrpage.cpp)")
  12. #include "compdata.h"
  13. #include "schmutil.h"
  14. #include "select.h"
  15. #include "attrpage.h"
  16. const CDialogControlsInfo ctrls[] =
  17. {
  18. // { IDC_CLASS_MMB_MANDATORY_ATTRIBUTES, g_MustContain, FALSE },
  19. // { IDC_CLASS_MMB_OPTIONAL_ATTRIBUTES, g_MayContain, FALSE },
  20. { IDC_CLASS_MMB_OPTIONAL_ADD, g_MayContain, FALSE },
  21. { IDC_CLASS_MMB_OPTIONAL_REMOVE, g_MayContain, FALSE },
  22. } ;
  23. const DWORD ClassAttributePage::help_map[] =
  24. {
  25. IDI_CLASS, NO_HELP,
  26. IDC_CLASS_MMB_NAME_STATIC, NO_HELP,
  27. IDC_CLASS_MMB_MANDATORY_ATTRIBUTES, IDH_CLASS_MMB_MANDATORY_ATTRIBUTES,
  28. IDC_CLASS_MMB_OPTIONAL_ATTRIBUTES, IDH_CLASS_MMB_OPTIONAL_ATTRIBUTES,
  29. IDC_CLASS_MMB_SYSCLASS_STATIC, NO_HELP,
  30. IDC_CLASS_MMB_OPTIONAL_ADD, IDH_CLASS_MMB_OPTIONAL_ADD,
  31. IDC_CLASS_MMB_OPTIONAL_REMOVE, IDH_CLASS_MMB_OPTIONAL_REMOVE,
  32. 0,0
  33. };
  34. ClassAttributePage::ClassAttributePage(
  35. ComponentData *pScope,
  36. LPDATAOBJECT lpDataObject )
  37. :
  38. CPropertyPageAutoDelete(ClassAttributePage::IDD),
  39. m_pIADsObject( NULL ),
  40. fSystemClass( FALSE ),
  41. m_pSchemaObject( NULL ),
  42. pScopeControl( pScope ),
  43. lpScopeDataObj( lpDataObject )
  44. {
  45. ASSERT(pScopeControl);
  46. ASSERT(lpDataObject);
  47. }
  48. ClassAttributePage::~ClassAttributePage()
  49. {
  50. if (NULL != m_pIADsObject)
  51. {
  52. m_pIADsObject->Release();
  53. }
  54. if (NULL != m_pSchemaObject)
  55. {
  56. pScopeControl->g_SchemaCache.ReleaseRef( m_pSchemaObject );
  57. }
  58. }
  59. void
  60. ClassAttributePage::Load(
  61. Cookie& CookieRef
  62. ) {
  63. //
  64. // Store the cookie object pointer.
  65. //
  66. m_pCookie = &CookieRef;
  67. return;
  68. }
  69. BOOL
  70. ClassAttributePage::OnSetActive()
  71. {
  72. // always enable the Apply button
  73. SetModified(TRUE);
  74. return TRUE;
  75. }
  76. BOOL
  77. ClassAttributePage::OnInitDialog()
  78. {
  79. HRESULT hr = S_OK;
  80. ASSERT( NULL == m_pIADsObject && m_szAdsPath.IsEmpty() );
  81. //
  82. // Get the schema cache object and the actual ADS object.
  83. //
  84. m_pSchemaObject = pScopeControl->g_SchemaCache.LookupSchemaObjectByCN(
  85. (PCWSTR)m_pCookie->strSchemaObject,
  86. SCHMMGMT_CLASS );
  87. if ( m_pSchemaObject ) {
  88. pScopeControl->GetSchemaObjectPath( m_pSchemaObject->commonName, m_szAdsPath );
  89. if ( !m_szAdsPath.IsEmpty() ) {
  90. hr = SchemaOpenObject( (LPWSTR)(LPCWSTR)m_szAdsPath,
  91. IID_IADs,
  92. (void **)&m_pIADsObject );
  93. ASSERT( SUCCEEDED(hr) );
  94. }
  95. }
  96. //
  97. // If we have no ADS object, we should error out!
  98. //
  99. if ( !m_pIADsObject ) {
  100. DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_NO_SCHEMA_OBJECT );
  101. ASSERT(FALSE);
  102. return TRUE;
  103. }
  104. //
  105. // get the current values.
  106. //
  107. VARIANT AdsResult;
  108. VariantInit( &AdsResult );
  109. //
  110. // ObjectName
  111. //
  112. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  113. hr = m_pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_DisplayName),
  114. &AdsResult );
  115. if ( SUCCEEDED( hr ) ) {
  116. ASSERT( AdsResult.vt == VT_BSTR );
  117. ObjectName = AdsResult.bstrVal;
  118. VariantClear( &AdsResult );
  119. }
  120. // NTRAID#NTBUG9-460503,460511-2001/09/10-lucios
  121. // Replaced SysClass Computation by Making the window visible
  122. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  123. hr = m_pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_SystemOnly),
  124. &AdsResult );
  125. if ( SUCCEEDED( hr ) ) {
  126. ASSERT( AdsResult.vt == VT_BOOL );
  127. fSystemClass = AdsResult.boolVal;
  128. if ( fSystemClass ) {
  129. ASSERT(GetDlgItem( IDC_CLASS_MMB_SYSCLASS_STATIC ) != NULL);
  130. GetDlgItem( IDC_CLASS_MMB_SYSCLASS_STATIC )->ShowWindow( SW_SHOW );
  131. }
  132. VariantClear( &AdsResult );
  133. }
  134. //
  135. // Determine the mandatory attributes
  136. //
  137. VARIANT varAttributes;
  138. VariantInit( &varAttributes );
  139. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  140. hr = m_pIADsObject->GetEx( CComBSTR(g_MustContain), &varAttributes );
  141. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  142. if( SUCCEEDED(hr) )
  143. {
  144. hr = VariantToStringList( varAttributes, strlistMandatory );
  145. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  146. }
  147. VariantClear( &varAttributes );
  148. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  149. hr = m_pIADsObject->GetEx( CComBSTR(g_SystemMustContain), &varAttributes );
  150. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  151. if( SUCCEEDED(hr) )
  152. {
  153. hr = VariantToStringList( varAttributes, strlistSystemMandatory );
  154. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  155. }
  156. VariantClear( &varAttributes );
  157. //
  158. // Determine the optional attributes
  159. //
  160. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  161. hr = m_pIADsObject->GetEx( CComBSTR(g_MayContain), &varAttributes );
  162. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  163. if( SUCCEEDED(hr) )
  164. {
  165. hr = VariantToStringList( varAttributes, strlistOptional );
  166. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  167. }
  168. VariantClear( &varAttributes );
  169. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  170. hr = m_pIADsObject->GetEx( CComBSTR(g_SystemMayContain), &varAttributes );
  171. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  172. if( SUCCEEDED(hr) )
  173. {
  174. hr = VariantToStringList( varAttributes, strlistSystemOptional );
  175. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  176. }
  177. VariantClear( &varAttributes );
  178. hr = DissableReadOnlyAttributes( this, m_pIADsObject, ctrls, sizeof(ctrls)/sizeof(ctrls[0]) );
  179. // NTRAID#NTBUG9-503619-2002/05/15-lucios
  180. hr = S_OK;
  181. // This call must be done before DDX binding
  182. m_listboxOptional.InitType( pScopeControl,
  183. SELECT_ATTRIBUTES,
  184. IDC_CLASS_MMB_OPTIONAL_REMOVE,
  185. &strlistSystemOptional
  186. );
  187. CPropertyPage::OnInitDialog();
  188. return TRUE;
  189. }
  190. void
  191. ClassAttributePage::DoDataExchange(
  192. CDataExchange *pDX
  193. ) {
  194. HRESULT hr = S_OK;
  195. CPropertyPage::DoDataExchange( pDX );
  196. //{{AFX_DATA_MAP(ClassAttributePage)
  197. DDX_Control(pDX, IDC_CLASS_MMB_MANDATORY_ATTRIBUTES, m_listboxMandatory);
  198. DDX_Control(pDX, IDC_CLASS_MMB_OPTIONAL_ATTRIBUTES, m_listboxOptional);
  199. DDX_Text( pDX, IDC_CLASS_MMB_NAME_STATIC, ObjectName );
  200. //}}AFX_DATA_MAP
  201. if ( !pDX->m_bSaveAndValidate )
  202. {
  203. //
  204. // Fill the mandatory attributes list box.
  205. //
  206. m_listboxMandatory.ResetContent();
  207. hr = InsertEditItems( m_listboxMandatory, strlistMandatory );
  208. ASSERT( SUCCEEDED(hr) );
  209. hr = InsertEditItems( m_listboxMandatory, strlistSystemMandatory );
  210. ASSERT( SUCCEEDED(hr) );
  211. //
  212. // Fill the possible optionals list box.
  213. //
  214. m_listboxOptional.ResetContent();
  215. hr = InsertEditItems( m_listboxOptional, strlistOptional );
  216. ASSERT( SUCCEEDED(hr) );
  217. hr = InsertEditItems( m_listboxOptional, strlistSystemOptional );
  218. ASSERT( SUCCEEDED(hr) );
  219. m_listboxOptional.OnSelChange();
  220. }
  221. else
  222. {
  223. //
  224. // All changes that we save are tied to button control routines.
  225. //
  226. strlistMandatory.RemoveAll();
  227. hr = RetrieveEditItemsWithExclusions(
  228. m_listboxMandatory,
  229. strlistMandatory,
  230. &strlistSystemMandatory
  231. );
  232. ASSERT( SUCCEEDED(hr) );
  233. strlistOptional.RemoveAll();
  234. hr = RetrieveEditItemsWithExclusions(
  235. m_listboxOptional,
  236. strlistOptional,
  237. &strlistSystemOptional
  238. );
  239. ASSERT( SUCCEEDED(hr) );
  240. }
  241. }
  242. BEGIN_MESSAGE_MAP(ClassAttributePage, CPropertyPage)
  243. ON_BN_CLICKED(IDC_CLASS_MMB_OPTIONAL_ADD, OnButtonOptionalAttributeAdd)
  244. ON_BN_CLICKED(IDC_CLASS_MMB_OPTIONAL_REMOVE, OnButtonOptionalAttributeRemove)
  245. ON_LBN_SELCHANGE(IDC_CLASS_MMB_OPTIONAL_ATTRIBUTES, OnOptionalSelChange)
  246. ON_MESSAGE(WM_HELP, OnHelp)
  247. ON_MESSAGE(WM_CONTEXTMENU, OnContextHelp)
  248. END_MESSAGE_MAP()
  249. BOOL
  250. ClassAttributePage::OnApply()
  251. {
  252. ASSERT( NULL != m_pIADsObject);
  253. ASSERT( NULL != m_pSchemaObject);
  254. HRESULT hr = S_OK;
  255. BOOL fApplyAbort = FALSE; // stop later saves
  256. BOOL fApplyFailed = FALSE; // should not close the box
  257. ListEntry *pNewList;
  258. if ( m_listboxOptional.IsModified() )
  259. {
  260. //
  261. // Update the optional attributes
  262. //
  263. VARIANT AdsValue;
  264. VariantInit( &AdsValue );
  265. hr = StringListToVariant( AdsValue, strlistOptional );
  266. // NTRAID#NTBUG9-543624-2002/02/15-dantra-Result of StringListToVariant being ignored resulting in call to IADs::PutEx with incorrect data
  267. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  268. if( SUCCEEDED( hr ) ) hr = m_pIADsObject->PutEx( ADS_PROPERTY_UPDATE, CComBSTR(g_MayContain), AdsValue );
  269. VariantClear( &AdsValue );
  270. // NTRAID#NTBUG9-542354-2002/02/14-dantra-Errors returned by IADs::Put and PutEx are being masked.
  271. if( SUCCEEDED( hr ) ) hr = m_pIADsObject->SetInfo();
  272. if ( SUCCEEDED( hr )) {
  273. //
  274. // Update the cached data.
  275. //
  276. hr = StringListToColumnList( pScopeControl,
  277. strlistOptional,
  278. &pNewList );
  279. if ( SUCCEEDED( hr )) {
  280. pScopeControl->g_SchemaCache.FreeColumnList( m_pSchemaObject->mayContain );
  281. m_pSchemaObject->mayContain = pNewList;
  282. }
  283. //
  284. // Continue with the directory operation even if
  285. // we couldn't update the cache.
  286. //
  287. hr = S_OK;
  288. }
  289. }
  290. if ( hr == ADS_EXTENDED_ERROR ) {
  291. DoExtErrMsgBox();
  292. }
  293. else if ( FAILED(hr) )
  294. {
  295. if( ERROR_DS_UNWILLING_TO_PERFORM == HRESULT_CODE(hr) )
  296. {
  297. fApplyFailed = TRUE;
  298. DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_CHANGE_REJECT );
  299. }
  300. else
  301. {
  302. fApplyAbort = TRUE;
  303. DoErrMsgBox( ::GetActiveWindow(), TRUE, GetErrorMessage(hr,TRUE) );
  304. }
  305. }
  306. else
  307. {
  308. m_listboxOptional.SetModified( FALSE );
  309. SetModified( FALSE );
  310. //
  311. // Refresh the display!
  312. //
  313. pScopeControl->QueryConsole()->UpdateAllViews(
  314. lpScopeDataObj, SCHMMGMT_CLASS, SCHMMGMT_UPDATEVIEW_REFRESH );
  315. }
  316. return !fApplyAbort && !fApplyFailed ; // return TRUE if nothing happened
  317. }
  318. void ClassAttributePage::OnOptionalSelChange()
  319. {
  320. m_listboxOptional.OnSelChange();
  321. }
  322. void ClassAttributePage::OnButtonOptionalAttributeRemove()
  323. {
  324. if( m_listboxOptional.RemoveListBoxItem() )
  325. SetModified( TRUE );
  326. }
  327. void
  328. ClassAttributePage::OnButtonOptionalAttributeAdd()
  329. {
  330. if( m_listboxOptional.AddNewObjectToList() )
  331. SetModified( TRUE );
  332. }