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.

860 lines
25 KiB

  1. #include "stdafx.h"
  2. #include "compdata.h"
  3. #include "select.h"
  4. #include "classgen.hpp"
  5. /////////////////////////////////////////////////////////////////
  6. // ClassGeneralPage
  7. const CDialogControlsInfo ctrls[] =
  8. {
  9. { IDC_CLASS_GENERAL_DESCRIPTION_EDIT, g_Description, TRUE },
  10. { IDC_CATEGORY_CHANGE, g_DefaultCategory, FALSE },
  11. { IDC_CLASS_GENERAL_DISPLAYABLE_CHECK, g_ShowInAdvViewOnly, FALSE },
  12. { IDC_CLASS_DEACTIVATE, g_isDefunct, FALSE }
  13. };
  14. const DWORD ClassGeneralPage::help_map[] =
  15. {
  16. IDI_CLASS, NO_HELP,
  17. IDC_CLASS_GENERAL_NAME_STATIC, NO_HELP,
  18. IDC_CLASS_GENERAL_DESCRIPTION_EDIT, IDH_CLASS_GENERAL_DESCRIPTION_EDIT,
  19. IDC_CLASS_GENERAL_LDN, IDH_CLASS_GENERAL_LDN,
  20. IDC_CLASS_GENERAL_OID_EDIT, IDH_CLASS_GENERAL_OID_EDIT,
  21. IDC_CLASS_GENERAL_CATEGORY_COMBO, IDH_CLASS_GENERAL_CATEGORY_COMBO,
  22. IDC_CATEGORY_EDIT, IDH_CATEGORY_EDIT,
  23. IDC_CATEGORY_CHANGE, IDH_CATEGORY_CHANGE,
  24. IDC_CLASS_GENERAL_DISPLAYABLE_CHECK, IDH_CLASS_GENERAL_DISPLAYABLE_CHECK,
  25. IDC_CLASS_DEACTIVATE, IDH_CLASS_DEACTIVATE,
  26. IDC_CLASS_GENERAL_SYSCLASS_STATIC, NO_HELP,
  27. 0, 0
  28. };
  29. //
  30. // The MFC Message Map.
  31. //
  32. BEGIN_MESSAGE_MAP( ClassGeneralPage, CDialog )
  33. ON_BN_CLICKED( IDC_CATEGORY_CHANGE, OnButtonCategoryChange )
  34. ON_MESSAGE(WM_HELP, OnHelp)
  35. ON_MESSAGE(WM_CONTEXTMENU, OnContextHelp)
  36. ON_BN_CLICKED(IDC_CLASS_DEACTIVATE, OnDeactivateClick)
  37. END_MESSAGE_MAP()
  38. //
  39. // Class dialog box routines.
  40. //
  41. ClassGeneralPage::ClassGeneralPage( ComponentData *pScope ) :
  42. CPropertyPageAutoDelete( IDD_CLASS_GENERAL ),
  43. fDataLoaded( FALSE ),
  44. pIADsObject( NULL ),
  45. pObject( NULL ),
  46. pScopeControl( pScope )
  47. { ; }
  48. ClassGeneralPage::~ClassGeneralPage() {
  49. //
  50. // Always make sure we free the IADs object.
  51. //
  52. if ( pIADsObject ) {
  53. pIADsObject->Release();
  54. pIADsObject = NULL;
  55. }
  56. //
  57. // And release the cache!
  58. //
  59. if ( pObject ) {
  60. pScopeControl->g_SchemaCache.ReleaseRef( pObject );
  61. }
  62. }
  63. BOOL
  64. ClassGeneralPage::OnInitDialog()
  65. {
  66. CPropertyPage::OnInitDialog();
  67. CWnd* wnd = GetDlgItem(IDC_CLASS_GENERAL_DESCRIPTION_EDIT);
  68. ASSERT(wnd);
  69. if (wnd)
  70. {
  71. wnd->SendMessage(EM_SETLIMITTEXT, (WPARAM) 1024, 0);
  72. }
  73. // NTRAID#NTBUG9-460503,460511-2001/09/10-lucios
  74. // Replaced SysClass Computation by Making the window visible in OnInitDialog
  75. if(pIADsObject != NULL)
  76. { // DoDataExchange has gotten a good pIADsObject or the dialog
  77. // will be closed in OnSetActive
  78. VARIANT AdsResult;
  79. VariantInit( &AdsResult );
  80. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  81. HRESULT hr = pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_SystemOnly),
  82. &AdsResult );
  83. if ( SUCCEEDED( hr ) ) {
  84. ASSERT( AdsResult.vt == VT_BOOL );
  85. if ( AdsResult.boolVal ) {
  86. ASSERT(GetDlgItem( IDC_CLASS_GENERAL_SYSCLASS_STATIC ) != NULL);
  87. GetDlgItem( IDC_CLASS_GENERAL_SYSCLASS_STATIC )->ShowWindow( SW_SHOW );
  88. }
  89. VariantClear( &AdsResult );
  90. }
  91. }
  92. return TRUE;
  93. }
  94. BOOL
  95. ClassGeneralPage::OnSetActive()
  96. {
  97. // If pIADsObject is NULL, close dialog box
  98. if( CPropertyPage::OnSetActive() )
  99. {
  100. if ( !pIADsObject )
  101. {
  102. return FALSE;
  103. }
  104. else
  105. {
  106. // always enable the Apply button
  107. SetModified(TRUE);
  108. return TRUE;
  109. }
  110. }
  111. else
  112. return FALSE;
  113. }
  114. void
  115. ClassGeneralPage::Load(
  116. Cookie& CookieRef
  117. ) {
  118. //
  119. // Store the cookie object pointer. Everything
  120. // else gets loaded when the page is displayed.
  121. //
  122. pCookie = &CookieRef;
  123. return;
  124. }
  125. void
  126. ClassGeneralPage::DoDataExchange(
  127. CDataExchange *pDX
  128. )
  129. /***
  130. This routine picks up the object name out of the
  131. cookie and then looks up the ADSI path name out of
  132. the schema object cache. It then drives the dialog
  133. box directly from the ADS object.
  134. ***/
  135. {
  136. CThemeContextActivator activator;
  137. HRESULT hr;
  138. CString szAdsPath;
  139. VARIANT AdsResult;
  140. DWORD dwClassType;
  141. CPropertyPage::DoDataExchange( pDX );
  142. VariantInit( &AdsResult );
  143. if ( !pDX->m_bSaveAndValidate ) {
  144. //
  145. // If this is not the initial load and is not
  146. // the save, just use the data that we've loaded.
  147. //
  148. if ( !fDataLoaded ) {
  149. CWaitCursor wait;
  150. //
  151. // Get the schema cache object and the actual ADS object.
  152. // Keep both around while the page is loaded.
  153. //
  154. pObject = pScopeControl->g_SchemaCache.LookupSchemaObjectByCN(
  155. pCookie->strSchemaObject,
  156. SCHMMGMT_CLASS );
  157. if ( pObject ) {
  158. pScopeControl->GetSchemaObjectPath( pObject->commonName, szAdsPath );
  159. if ( !szAdsPath.IsEmpty() ) {
  160. hr = SchemaOpenObject( (LPWSTR)(LPCWSTR)szAdsPath,
  161. IID_IADs,
  162. (void **)&pIADsObject );
  163. }
  164. }
  165. //
  166. // If we have no ADS object, we should error out!
  167. //
  168. if ( !pIADsObject ) {
  169. DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_NO_SCHEMA_OBJECT );
  170. // Because there is no pIADsObject, OnSetActive() will close dialog box
  171. return;
  172. }
  173. //
  174. // ObjectName - Use the ldapDisplayName to be consistent with
  175. // the other admin components.
  176. //
  177. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  178. hr = pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_DisplayName),
  179. &AdsResult );
  180. if ( SUCCEEDED( hr ) ) {
  181. ASSERT( AdsResult.vt == VT_BSTR );
  182. ObjectName = AdsResult.bstrVal;
  183. VariantClear( &AdsResult );
  184. }
  185. //
  186. //
  187. // CommonName
  188. //
  189. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  190. hr = pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_CN),
  191. &AdsResult );
  192. if ( SUCCEEDED( hr ) ) {
  193. ASSERT( AdsResult.vt == VT_BSTR );
  194. DisplayName = AdsResult.bstrVal;
  195. VariantClear( &AdsResult );
  196. }
  197. //
  198. // Description
  199. //
  200. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  201. hr = pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_Description),
  202. &AdsResult );
  203. if ( SUCCEEDED( hr ) ) {
  204. ASSERT( AdsResult.vt == VT_BSTR );
  205. Description = AdsResult.bstrVal;
  206. DDXDescription = AdsResult.bstrVal;
  207. VariantClear( &AdsResult );
  208. }
  209. //
  210. // OID
  211. //
  212. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  213. hr = pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_GlobalClassID),
  214. &AdsResult );
  215. if ( SUCCEEDED( hr ) ) {
  216. ASSERT( AdsResult.vt == VT_BSTR );
  217. OidString = AdsResult.bstrVal;
  218. VariantClear( &AdsResult );
  219. }
  220. //
  221. // Displayable
  222. //
  223. Displayable = TRUE;
  224. DDXDisplayable = TRUE;
  225. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  226. hr = pIADsObject->Get(CComBSTR(g_ShowInAdvViewOnly), &AdsResult);
  227. if ( SUCCEEDED( hr ) ) {
  228. ASSERT( AdsResult.vt == VT_BOOL );
  229. if ( AdsResult.boolVal == -1 ) {
  230. Displayable = FALSE;
  231. DDXDisplayable = FALSE;
  232. }
  233. VariantClear( &AdsResult );
  234. }
  235. //
  236. // Defunct
  237. //
  238. Defunct = FALSE;
  239. DDXDefunct = FALSE;
  240. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  241. hr = pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_isDefunct),
  242. &AdsResult );
  243. if ( SUCCEEDED( hr ) ) {
  244. ASSERT( AdsResult.vt == VT_BOOL );
  245. if ( AdsResult.boolVal == -1 ) {
  246. Defunct = TRUE;
  247. DDXDefunct = TRUE;
  248. }
  249. VariantClear( &AdsResult );
  250. }
  251. // NTRAID#NTBUG9-460503,460511-2001/09/10-lucios
  252. // Replaced SysClass Computation by Making the window visible in OnInitDialog
  253. //
  254. // ClassType
  255. //
  256. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  257. hr = pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_ObjectClassCategory),
  258. &AdsResult );
  259. if ( SUCCEEDED( hr ) ) {
  260. ASSERT( AdsResult.vt == VT_I4 );
  261. dwClassType = V_I4( &AdsResult );
  262. VariantClear( &AdsResult );
  263. switch ( dwClassType ) {
  264. case 0:
  265. ClassType = g_88Class;
  266. break;
  267. case 1:
  268. ClassType = g_StructuralClass;
  269. break;
  270. case 2:
  271. ClassType = g_AbstractClass;
  272. break;
  273. case 3:
  274. ClassType = g_AuxClass;
  275. break;
  276. default:
  277. ClassType = g_Unknown;
  278. break;
  279. }
  280. }
  281. //
  282. // Category
  283. //
  284. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  285. hr = pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_DefaultCategory),
  286. &AdsResult );
  287. if ( SUCCEEDED( hr ) ) {
  288. ASSERT( V_VT(&AdsResult) == VT_BSTR );
  289. CString strCN;
  290. if( SUCCEEDED( pScopeControl->GetLeafObjectFromDN( V_BSTR(&AdsResult), strCN ) ))
  291. {
  292. //
  293. // Look up the ldapDisplayName.
  294. //
  295. SchemaObject * pCategory =
  296. pScopeControl->g_SchemaCache.LookupSchemaObjectByCN( strCN, SCHMMGMT_CLASS );
  297. if ( pCategory )
  298. {
  299. Category = DDXCategory = pCategory->ldapDisplayName;
  300. pScopeControl->g_SchemaCache.ReleaseRef( pCategory );
  301. }
  302. else
  303. {
  304. Category = DDXCategory = strCN;
  305. }
  306. }
  307. VariantClear( &AdsResult );
  308. }
  309. // Determine if this is a category 1 object & disable read-only fields
  310. BOOL fIsSystemObject = FALSE;
  311. hr = IsCategory1Object( pIADsObject, fIsSystemObject );
  312. if( SUCCEEDED(hr) && fIsSystemObject )
  313. {
  314. ASSERT( GetDlgItem(IDC_CATEGORY_CHANGE) );
  315. ASSERT( GetDlgItem(IDC_CLASS_DEACTIVATE) );
  316. GetDlgItem(IDC_CATEGORY_CHANGE)->EnableWindow( FALSE );
  317. GetDlgItem(IDC_CLASS_DEACTIVATE)->EnableWindow( FALSE );
  318. }
  319. hr = DissableReadOnlyAttributes( this, pIADsObject, ctrls, sizeof(ctrls)/sizeof(ctrls[0]) );
  320. // NTRAID#NTBUG9-503619-2002/05/15-lucios
  321. hr = S_OK;
  322. // warn the user if this is a read/write defunct object
  323. ASSERT( GetDlgItem(IDC_CLASS_DEACTIVATE) );
  324. if( DDXDefunct &&
  325. GetDlgItem(IDC_CLASS_DEACTIVATE)->IsWindowEnabled() )
  326. {
  327. AfxMessageBox( IDS_WARNING_DEFUNCT, MB_OK | MB_ICONINFORMATION );
  328. }
  329. //
  330. // Remember that the data is loaded.
  331. //
  332. fDataLoaded = TRUE;
  333. }
  334. }
  335. //
  336. // Set up the dialog data exchange.
  337. //
  338. DDX_Text( pDX, IDC_CLASS_GENERAL_NAME_STATIC, ObjectName );
  339. DDX_Text( pDX, IDC_CLASS_GENERAL_CATEGORY_COMBO, ClassType );
  340. DDX_Text( pDX, IDC_CLASS_GENERAL_DESCRIPTION_EDIT, DDXDescription );
  341. DDX_Text( pDX, IDC_CLASS_GENERAL_LDN, DisplayName );
  342. DDX_Text( pDX, IDC_CLASS_GENERAL_OID_EDIT, OidString );
  343. DDX_Text( pDX, IDC_CATEGORY_EDIT, DDXCategory );
  344. DDX_Check( pDX, IDC_CLASS_GENERAL_DISPLAYABLE_CHECK, DDXDisplayable );
  345. // Since we want the checkbox label to be positive
  346. // the value is actually the opposite of defunct
  347. int checkValue = !Defunct;
  348. DDX_Check( pDX, IDC_CLASS_DEACTIVATE, checkValue );
  349. DDXDefunct = !checkValue;
  350. return;
  351. }
  352. BOOL
  353. ClassGeneralPage::OnApply(
  354. VOID
  355. ) {
  356. HRESULT hr;
  357. VARIANT AdsValue;
  358. BOOL fChangesMade = FALSE;
  359. BOOL fApplyAbort = FALSE; // stop later saves
  360. BOOL fApplyFailed = FALSE; // should not close the box
  361. if ( !UpdateData(TRUE) ) {
  362. return FALSE;
  363. }
  364. //
  365. // We have to flush the IADS property cache if we
  366. // have a failure so later operations won't fail because
  367. // of a bad cached attribute.
  368. //
  369. IADsPropertyList *pPropertyList;
  370. hr = pIADsObject->QueryInterface( IID_IADsPropertyList,
  371. reinterpret_cast<void**>(&pPropertyList) );
  372. if ( FAILED( hr ) ) {
  373. pPropertyList = NULL;
  374. fApplyAbort = TRUE;
  375. }
  376. //
  377. // We only care if the description, class type, or
  378. // displayable attributes changed.
  379. //
  380. VariantInit( &AdsValue );
  381. //
  382. // Defunct -- in case it was deactivated, activate the object first
  383. //
  384. // NTRAID#NTBUG9-477292-2001/10/10-lucios
  385. // && !DDXDefunct was taken out and fChangesMade=TRUE added
  386. if( !fApplyAbort && DDXDefunct != Defunct )
  387. {
  388. hr = ChangeDefunctState( DDXDefunct, Defunct, pPropertyList, fApplyAbort, fApplyFailed );
  389. if (FAILED(hr)) fApplyAbort = TRUE;
  390. else fChangesMade = TRUE;
  391. }
  392. if ( !fApplyAbort && DDXDescription != Description ) {
  393. V_VT(&AdsValue) = VT_BSTR;
  394. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  395. V_BSTR(&AdsValue) = const_cast<BSTR>((LPCTSTR)DDXDescription);
  396. if ( DDXDescription.IsEmpty() ) {
  397. hr = pIADsObject->PutEx( ADS_PROPERTY_CLEAR,
  398. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  399. const_cast<BSTR>((LPCTSTR)g_Description),
  400. AdsValue );
  401. } else {
  402. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  403. hr = pIADsObject->Put( const_cast<BSTR>((LPCTSTR)g_Description),
  404. AdsValue );
  405. }
  406. // NTRAID#NTBUG9-542354-2002/02/14-dantra-Errors returned by IADs::Put and PutEx are being masked.
  407. if( SUCCEEDED( hr ) ) hr = pIADsObject->SetInfo();
  408. if ( SUCCEEDED( hr ) ) {
  409. pObject->description = DDXDescription;
  410. fChangesMade = TRUE;
  411. Description = DDXDescription;
  412. } else {
  413. pPropertyList->PurgePropertyList();
  414. if( ERROR_DS_UNWILLING_TO_PERFORM == HRESULT_CODE(hr) )
  415. {
  416. fApplyFailed = TRUE;
  417. DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_EDIT_DESC );
  418. }
  419. else
  420. {
  421. fApplyAbort = TRUE;
  422. DoErrMsgBox( ::GetActiveWindow(), TRUE, GetErrorMessage(hr,TRUE) );
  423. }
  424. }
  425. VariantInit( &AdsValue );
  426. }
  427. if ( !fApplyAbort && DDXDisplayable != Displayable ) {
  428. V_VT(&AdsValue) = VT_BOOL;
  429. if ( DDXDisplayable ) {
  430. V_BOOL(&AdsValue) = 0;
  431. } else {
  432. V_BOOL(&AdsValue) = -1;
  433. }
  434. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  435. hr = pIADsObject->Put( CComBSTR(g_ShowInAdvViewOnly), AdsValue);
  436. // NTRAID#NTBUG9-542354-2002/02/14-dantra-Errors returned by IADs::Put and PutEx are being masked.
  437. if( SUCCEEDED( hr ) ) hr = pIADsObject->SetInfo();
  438. if ( FAILED( hr ) ) {
  439. pPropertyList->PurgePropertyList();
  440. if( ERROR_DS_UNWILLING_TO_PERFORM == HRESULT_CODE(hr) )
  441. {
  442. fApplyFailed = TRUE;
  443. DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_EDIT_DISPLAYABLE );
  444. }
  445. else
  446. {
  447. fApplyAbort = TRUE;
  448. DoErrMsgBox( ::GetActiveWindow(), TRUE, GetErrorMessage(hr,TRUE) );
  449. }
  450. }
  451. else
  452. {
  453. Displayable = DDXDisplayable;
  454. }
  455. VariantInit( &AdsValue );
  456. }
  457. if ( !fApplyAbort && DDXCategory != Category ) {
  458. SchemaObject *pCategoryObject;
  459. CString DistName;
  460. hr = E_FAIL;
  461. V_VT(&AdsValue) = VT_BSTR;
  462. //
  463. // Map the commonName to the distinguished name.
  464. //
  465. pCategoryObject = pScopeControl->g_SchemaCache.LookupSchemaObject(
  466. DDXCategory,
  467. SCHMMGMT_CLASS );
  468. if ( pCategoryObject ) {
  469. pScopeControl->GetSchemaObjectPath(pCategoryObject->commonName, DistName, ADS_FORMAT_X500_DN );
  470. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  471. V_BSTR(&AdsValue) = const_cast<BSTR>((LPCTSTR)DistName);
  472. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  473. hr = pIADsObject->Put( const_cast<BSTR>((LPCTSTR)g_DefaultCategory),
  474. AdsValue );
  475. if( SUCCEEDED( hr ) ) hr = pIADsObject->SetInfo();
  476. }
  477. if ( FAILED( hr ) ) {
  478. pPropertyList->PurgePropertyList();
  479. if( ERROR_DS_UNWILLING_TO_PERFORM == HRESULT_CODE(hr) )
  480. {
  481. fApplyFailed = TRUE;
  482. DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_EDIT_CATEGORY );
  483. }
  484. else
  485. {
  486. fApplyAbort = TRUE;
  487. DoErrMsgBox( ::GetActiveWindow(), TRUE, GetErrorMessage(hr,TRUE) );
  488. }
  489. }
  490. else
  491. {
  492. Category = DDXCategory;
  493. }
  494. VariantInit( &AdsValue );
  495. }
  496. //
  497. // Defunct -- in case it was active, deactivate the object after we are done update
  498. //
  499. if( !fApplyAbort && DDXDefunct && DDXDefunct != Defunct )
  500. {
  501. hr = ChangeDefunctState( DDXDefunct, Defunct, pPropertyList, fApplyAbort, fApplyFailed );
  502. }
  503. if ( !fApplyAbort && fChangesMade ) {
  504. //
  505. // Call SetItem() so this gets refreshed.
  506. //
  507. SCOPEDATAITEM ScopeItem;
  508. CCookieListEntry *pEntry;
  509. BOOLEAN fFoundId = FALSE;
  510. if ( pScopeControl->g_ClassCookieList.pHead ) {
  511. pEntry = pScopeControl->g_ClassCookieList.pHead;
  512. if ( (pScopeControl->g_ClassCookieList.pHead)->pCookie == pCookie ) {
  513. fFoundId = TRUE;
  514. } else {
  515. while ( pEntry->pNext != pScopeControl->g_ClassCookieList.pHead ) {
  516. if ( pEntry->pCookie == pCookie ) {
  517. fFoundId = TRUE;
  518. break;
  519. }
  520. pEntry = pEntry->pNext;
  521. }
  522. }
  523. if ( fFoundId ) {
  524. // FUTURE-2002-03/94/2002-dantra-Although this is a safe usage of ZeroMemory, suggest changing
  525. // the definition of ScopeItem to SCOPEDATAITEM ScopeItem = {0} and removing the ZeroMemory call.
  526. ::ZeroMemory( &ScopeItem, sizeof(ScopeItem) );
  527. ScopeItem.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_PARENT;
  528. ScopeItem.displayname = MMC_CALLBACK;
  529. ScopeItem.relativeID = pScopeControl->g_ClassCookieList.hParentScopeItem;
  530. ScopeItem.nState = 0;
  531. ScopeItem.lParam = reinterpret_cast<LPARAM>((CCookie*)pCookie);
  532. ScopeItem.nImage = pScopeControl->QueryImage( *pCookie, FALSE );
  533. ScopeItem.nOpenImage = pScopeControl->QueryImage( *pCookie, TRUE );
  534. ScopeItem.ID = pEntry->hScopeItem;
  535. hr = pScopeControl->m_pConsoleNameSpace->SetItem( &ScopeItem );
  536. ASSERT( SUCCEEDED( hr ));
  537. }
  538. }
  539. }
  540. if ( pPropertyList ) {
  541. pPropertyList->Release();
  542. }
  543. return !fApplyAbort && !fApplyFailed ; // return TRUE if nothing happened
  544. }
  545. VOID
  546. ClassGeneralPage::OnButtonCategoryChange(
  547. ) {
  548. SchemaObject *pClass = NULL;
  549. INT_PTR DlgResult;
  550. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  551. CThemeContextActivator activator;
  552. //
  553. // Update any changes the user has made.
  554. //
  555. UpdateData( TRUE );
  556. //
  557. // Start the common select dialog box.
  558. //
  559. CSchmMgmtSelect dlgSelect( pScopeControl,
  560. SELECT_CLASSES,
  561. &pClass );
  562. DlgResult = dlgSelect.DoModal();
  563. //
  564. // When this returns, the class schema object
  565. // pointer will be filled into pClass.
  566. //
  567. if ( ( DlgResult == IDOK ) &&
  568. ( pClass != NULL ) ) {
  569. DDXCategory = pClass->ldapDisplayName;
  570. //
  571. // Push this back out to the UI.
  572. //
  573. UpdateData( FALSE );
  574. }
  575. return;
  576. }
  577. void
  578. ClassGeneralPage::OnDeactivateClick()
  579. {
  580. CThemeContextActivator activator;
  581. if( !IsDlgButtonChecked(IDC_CLASS_DEACTIVATE) )
  582. {
  583. if
  584. ( IDYES != AfxMessageBox
  585. (
  586. IDS_WARNING_DEFUNCT_SET,
  587. MB_YESNO | MB_DEFBUTTON2 | MB_ICONWARNING
  588. )
  589. )
  590. {
  591. CheckDlgButton( IDC_CLASS_DEACTIVATE, BST_CHECKED );
  592. }
  593. }
  594. }
  595. HRESULT
  596. ClassGeneralPage::ChangeDefunctState( BOOL DDXDefunct,
  597. BOOL & Defunct,
  598. IADsPropertyList * pPropertyList,
  599. BOOL & fApplyAbort,
  600. BOOL & fApplyFailed )
  601. {
  602. ASSERT( !fApplyAbort && DDXDefunct != Defunct );
  603. VARIANT AdsValue;
  604. HRESULT hr = S_OK;
  605. VariantInit( &AdsValue );
  606. V_VT(&AdsValue) = VT_BOOL;
  607. if ( DDXDefunct ) {
  608. V_BOOL(&AdsValue) = -1;
  609. } else {
  610. V_BOOL(&AdsValue) = 0;
  611. }
  612. // NTRAID#NTBUG9-540866-2002/02/13-dantra-Schema Manager: passing WCHAR * instead of BSTR to method requiring a BSTR
  613. hr = pIADsObject->Put( const_cast<BSTR>((LPCTSTR)g_isDefunct),
  614. AdsValue );
  615. // NTRAID#NTBUG9-542354-2002/02/14-dantra-Errors returned by IADs::Put and PutEx are being masked.
  616. if( SUCCEEDED( hr ) ) hr = pIADsObject->SetInfo();
  617. if ( FAILED( hr ) ) {
  618. pPropertyList->PurgePropertyList();
  619. if( ERROR_DS_UNWILLING_TO_PERFORM == HRESULT_CODE(hr) )
  620. {
  621. fApplyFailed = TRUE;
  622. DoErrMsgBox( ::GetActiveWindow(),
  623. TRUE,
  624. DDXDefunct ? IDS_ERR_EDIT_DEFUNCT_SET : IDS_ERR_EDIT_DEFUNCT_REMOVE );
  625. }
  626. else
  627. {
  628. fApplyAbort = TRUE;
  629. DoErrMsgBox( ::GetActiveWindow(), TRUE, GetErrorMessage(hr,TRUE) );
  630. }
  631. } else {
  632. pObject->isDefunct = DDXDefunct;
  633. Defunct = DDXDefunct;
  634. }
  635. return hr;
  636. }