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.

730 lines
24 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-1999 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // NetName.cpp
  7. //
  8. // Abstract:
  9. // Implementation of the CNetworkNameParamsPage class.
  10. //
  11. // Author:
  12. // David Potter (davidp) June 28, 1996
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "CluAdmX.h"
  21. #include "ExtObj.h"
  22. #include "NetName.h"
  23. #include "DDxDDv.h"
  24. #include "ExcOper.h"
  25. #include "ClusName.h"
  26. #include "HelpData.h" // for g_rghelpmap*
  27. #ifdef _DEBUG
  28. #define new DEBUG_NEW
  29. #undef THIS_FILE
  30. static char THIS_FILE[] = __FILE__;
  31. #endif
  32. /////////////////////////////////////////////////////////////////////////////
  33. // CNetworkNameParamsPage property page
  34. /////////////////////////////////////////////////////////////////////////////
  35. IMPLEMENT_DYNCREATE(CNetworkNameParamsPage, CBasePropertyPage)
  36. /////////////////////////////////////////////////////////////////////////////
  37. // Message Maps
  38. BEGIN_MESSAGE_MAP(CNetworkNameParamsPage, CBasePropertyPage)
  39. //{{AFX_MSG_MAP(CNetworkNameParamsPage)
  40. ON_EN_CHANGE(IDC_PP_NETNAME_PARAMS_NAME, OnChangeName)
  41. ON_BN_CLICKED(IDC_PP_NETNAME_PARAMS_RENAME, OnRename)
  42. ON_BN_CLICKED(IDC_PP_NETNAME_PARAMS_CHECKBOX_DNS, CBasePropertyPage::OnChangeCtrl)
  43. ON_BN_CLICKED(IDC_PP_NETNAME_PARAMS_CHECKBOX_KERBEROS, CBasePropertyPage::OnChangeCtrl)
  44. //}}AFX_MSG_MAP
  45. // TODO: Modify the following lines to represent the data displayed on this page.
  46. END_MESSAGE_MAP()
  47. /////////////////////////////////////////////////////////////////////////////
  48. //++
  49. //
  50. // CNetworkNameParamsPage::CNetworkNameParamsPage
  51. //
  52. // Routine Description:
  53. // Default constructor.
  54. //
  55. // Arguments:
  56. // None.
  57. //
  58. // Return Value:
  59. // None.
  60. //
  61. //--
  62. /////////////////////////////////////////////////////////////////////////////
  63. CNetworkNameParamsPage::CNetworkNameParamsPage(void)
  64. : CBasePropertyPage(g_aHelpIDs_IDD_PP_NETNAME_PARAMETERS, g_aHelpIDs_IDD_WIZ_NETNAME_PARAMETERS)
  65. {
  66. // TODO: Modify the following lines to represent the data displayed on this page.
  67. //{{AFX_DATA_INIT(CNetworkNameParamsPage)
  68. m_strName = _T("");
  69. m_strPrevName = _T("");
  70. m_nRequireDNS = BST_UNCHECKED;
  71. m_nRequireKerberos = BST_UNCHECKED;
  72. m_dwNetBIOSStatus = 0;
  73. m_dwDNSStatus = 0;
  74. m_dwKerberosStatus = 0;
  75. //}}AFX_DATA_INIT
  76. // Setup the property array.
  77. {
  78. m_rgProps[epropName].Set(REGPARAM_NETNAME_NAME, m_strName, m_strPrevName);
  79. m_rgProps[epropRequireDNS].Set(REGPARAM_NETNAME_REQUIRE_DNS, m_nRequireDNS, m_nPrevRequireDNS);
  80. m_rgProps[epropRequireKerberos].Set(REGPARAM_NETNAME_REQUIRE_KERBEROS, m_nRequireKerberos, m_nPrevRequireKerberos);
  81. m_rgProps[epropStatusNetBIOS].Set(REGPARAM_NETNAME_STATUS_NETBIOS, m_dwNetBIOSStatus, m_dwPrevNetBIOSStatus);
  82. m_rgProps[epropStatusDNS].Set(REGPARAM_NETNAME_STATUS_DNS, m_dwDNSStatus, m_dwPrevDNSStatus);
  83. m_rgProps[epropStatusKerberos].Set(REGPARAM_NETNAME_STATUS_KERBEROS, m_dwKerberosStatus, m_dwPrevKerberosStatus);
  84. } // Setup the property array
  85. m_dwFlags = 0;
  86. m_iddPropertyPage = IDD_PP_NETNAME_PARAMETERS;
  87. m_iddWizardPage = IDD_WIZ_NETNAME_PARAMETERS;
  88. } //*** CNetworkNameParamsPage::CNetworkNameParamsPage()
  89. /////////////////////////////////////////////////////////////////////////////
  90. //++
  91. //
  92. // CNetworkNameParamsPage::HrInit
  93. //
  94. // Routine Description:
  95. // Initialize the page.
  96. //
  97. // Arguments:
  98. // peo [IN OUT] Pointer to the extension object.
  99. //
  100. // Return Value:
  101. // S_OK Page initialized successfully.
  102. // hr Page failed to initialize.
  103. //
  104. //--
  105. /////////////////////////////////////////////////////////////////////////////
  106. HRESULT CNetworkNameParamsPage::HrInit(IN OUT CExtObject * peo)
  107. {
  108. HRESULT hr;
  109. CWaitCursor wc;
  110. DWORD sc;
  111. DWORD cbReturned;
  112. // Call the base class method.
  113. // This populates the m_rgProps struct.
  114. hr = CBasePropertyPage::HrInit(peo);
  115. if (!FAILED(hr))
  116. {
  117. m_strPrevName = m_strName;
  118. // Read the flags for this resource.
  119. sc = ClusterResourceControl(
  120. Peo()->PrdResData()->m_hresource,
  121. NULL,
  122. CLUSCTL_RESOURCE_GET_FLAGS,
  123. NULL,
  124. NULL,
  125. &m_dwFlags,
  126. sizeof(m_dwFlags),
  127. &cbReturned
  128. );
  129. if (sc != ERROR_SUCCESS)
  130. {
  131. CNTException nte(sc, NULL, NULL, FALSE /*bAutoDelete*/);
  132. nte.ReportError();
  133. nte.Delete();
  134. } // if: error retrieving data
  135. else
  136. {
  137. ASSERT(cbReturned == sizeof(m_dwFlags));
  138. } // else: data retrieved successfully
  139. } // if: base class init was successful
  140. return hr;
  141. } //*** CNetworkNameParamsPage::HrInit()
  142. /////////////////////////////////////////////////////////////////////////////
  143. //++
  144. //
  145. // CNetworkNameParamsPage::DoDataExchange
  146. //
  147. // Routine Description:
  148. // Do data exchange between the dialog and the class.
  149. //
  150. // Arguments:
  151. // pDX [IN OUT] Data exchange object
  152. //
  153. // Return Value:
  154. // None.
  155. //
  156. //--
  157. /////////////////////////////////////////////////////////////////////////////
  158. void CNetworkNameParamsPage::DoDataExchange(CDataExchange * pDX)
  159. {
  160. DWORD scError;
  161. BOOL bError;
  162. if (!pDX->m_bSaveAndValidate || !BSaved())
  163. {
  164. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  165. CWaitCursor wc;
  166. CString strNetName;
  167. // TODO: Modify the following lines to represent the data displayed on this page.
  168. //{{AFX_DATA_MAP(CNetworkNameParamsPage)
  169. DDX_Control(pDX, IDC_PP_NETNAME_PARAMS_NAME_LABEL, m_staticName);
  170. DDX_Control(pDX, IDC_PP_NETNAME_PARAMS_RENAME, m_pbRename);
  171. DDX_Control(pDX, IDC_PP_NETNAME_PARAMS_CORE_TEXT, m_staticCore);
  172. DDX_Control(pDX, IDC_PP_NETNAME_PARAMS_NAME, m_editName);
  173. DDX_Control(pDX, IDC_PP_NETNAME_PARAMS_CHECKBOX_DNS, m_cbRequireDNS);
  174. DDX_Control(pDX, IDC_PP_NETNAME_PARAMS_CHECKBOX_KERBEROS, m_cbRequireKerberos);
  175. DDX_Control(pDX, IDC_PP_NETNAME_PARAMS_STATUS_NETBIOS, m_editNetBIOSStatus);
  176. DDX_Control(pDX, IDC_PP_NETNAME_PARAMS_STATUS_DNS, m_editDNSStatus);
  177. DDX_Control(pDX, IDC_PP_NETNAME_PARAMS_STATUS_KERBEROS, m_editKerberosStatus);
  178. //
  179. // Get the status of the checkboxes.
  180. //
  181. DDX_Check(pDX, IDC_PP_NETNAME_PARAMS_CHECKBOX_DNS, m_nRequireDNS);
  182. DDX_Check(pDX, IDC_PP_NETNAME_PARAMS_CHECKBOX_KERBEROS, m_nRequireKerberos);
  183. //}}AFX_DATA_MAP
  184. bError = FALSE;
  185. if (pDX->m_bSaveAndValidate && !BBackPressed())
  186. {
  187. CLRTL_NAME_STATUS cnStatus;
  188. CString strMsg;
  189. UINT idsError;
  190. //
  191. // Get the name from the control into a temp variable
  192. //
  193. DDX_Text(pDX, IDC_PP_NETNAME_PARAMS_NAME, strNetName);
  194. DDV_RequiredText(pDX, IDC_PP_NETNAME_PARAMS_NAME, IDC_PP_NETNAME_PARAMS_NAME_LABEL, strNetName);
  195. DDV_MaxChars(pDX, strNetName, MAX_CLUSTERNAME_LENGTH);
  196. //
  197. // if turning off Kerb, warn the user about what they are about to do
  198. //
  199. if ( ( m_nRequireKerberos == 0 ) && ( m_nPrevRequireKerberos == 1 ) ) {
  200. strMsg.LoadString(IDS_WARNING_DISABLING_KERBEROS);
  201. int id = AfxMessageBox(strMsg, MB_YESNO | MB_DEFBUTTON2 | MB_ICONEXCLAMATION );
  202. if ( id == IDNO )
  203. {
  204. strMsg.Empty();
  205. pDX->Fail();
  206. bError = TRUE;
  207. }
  208. }
  209. //
  210. // validate the name if it changed
  211. //
  212. if ( (m_strName != strNetName ) &&
  213. (! ClRtlIsNetNameValid(strNetName, &cnStatus, FALSE /*CheckIfExists*/)) )
  214. {
  215. switch (cnStatus)
  216. {
  217. case NetNameTooLong:
  218. idsError = IDS_INVALID_NETWORK_NAME_TOO_LONG;
  219. break;
  220. case NetNameInvalidChars:
  221. idsError = IDS_INVALID_NETWORK_NAME_INVALID_CHARS;
  222. break;
  223. case NetNameInUse:
  224. idsError = IDS_INVALID_NETWORK_NAME_IN_USE;
  225. break;
  226. case NetNameDNSNonRFCChars:
  227. idsError = IDS_INVALID_NETWORK_NAME_INVALID_DNS_CHARS;
  228. break;
  229. case NetNameSystemError:
  230. {
  231. scError = GetLastError();
  232. CNTException nte(scError, IDS_ERROR_VALIDATING_NETWORK_NAME, (LPCWSTR) strNetName);
  233. nte.ReportError();
  234. pDX->Fail();
  235. }
  236. default:
  237. idsError = IDS_INVALID_NETWORK_NAME;
  238. break;
  239. } // switch: cnStatus
  240. strMsg.LoadString(idsError);
  241. if ( idsError == IDS_INVALID_NETWORK_NAME_INVALID_DNS_CHARS )
  242. {
  243. int id = AfxMessageBox(strMsg, MB_YESNO | MB_DEFBUTTON2 | MB_ICONEXCLAMATION );
  244. if ( id == IDNO )
  245. {
  246. strMsg.Empty();
  247. pDX->Fail();
  248. bError = TRUE;
  249. }
  250. }
  251. else
  252. {
  253. AfxMessageBox(strMsg, MB_ICONEXCLAMATION);
  254. strMsg.Empty(); // exception prep
  255. pDX->Fail();
  256. bError = TRUE;
  257. }
  258. } // if: ((m_strName != strNetName) && (! ClRtlIsNetNameValid(strNetName, &cnStatus, FALSE)) )
  259. //
  260. // Everything was validated - apply all of the changes.
  261. //
  262. if( FALSE == bError )
  263. {
  264. m_strName = strNetName;
  265. }
  266. }// if: (pDX->m_bSaveAndValidate && !BBackPressed())
  267. else // if: populating controls
  268. {
  269. CString m_strStatus;
  270. //
  271. // Populate the controls with data from the member variables.
  272. //
  273. DDX_Text(pDX, IDC_PP_NETNAME_PARAMS_NAME, m_strName);
  274. m_strStatus.Format( _T("%d (0x%08x)"), m_dwNetBIOSStatus, m_dwNetBIOSStatus );
  275. DDX_Text( pDX, IDC_PP_NETNAME_PARAMS_STATUS_NETBIOS, m_strStatus );
  276. m_strStatus.Format( _T("%d (0x%08x)"), m_dwDNSStatus, m_dwDNSStatus );
  277. DDX_Text( pDX, IDC_PP_NETNAME_PARAMS_STATUS_DNS, m_strStatus );
  278. m_strStatus.Format( _T("%d (0x%08x)"), m_dwKerberosStatus, m_dwKerberosStatus );
  279. DDX_Text( pDX, IDC_PP_NETNAME_PARAMS_STATUS_KERBEROS, m_strStatus );
  280. }
  281. } // if: not saving or haven't saved yet
  282. CBasePropertyPage::DoDataExchange(pDX);
  283. } //*** CNetworkNameParamsPage::DoDataExchange()
  284. /////////////////////////////////////////////////////////////////////////////
  285. //++
  286. //
  287. // CNetworkNameParamsPage::OnInitDialog
  288. //
  289. // Routine Description:
  290. // Handler for the WM_INITDIALOG message.
  291. //
  292. // Arguments:
  293. // None.
  294. //
  295. // Return Value:
  296. // TRUE We need the focus to be set for us.
  297. // FALSE We already set the focus to the proper control.
  298. //
  299. //--
  300. /////////////////////////////////////////////////////////////////////////////
  301. BOOL CNetworkNameParamsPage::OnInitDialog(void)
  302. {
  303. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  304. CBasePropertyPage::OnInitDialog();
  305. // Set limits on the edit controls.
  306. m_editName.SetLimitText(MAX_CLUSTERNAME_LENGTH);
  307. // Set up the checkboxes.
  308. m_cbRequireDNS.EnableWindow( TRUE );
  309. m_cbRequireKerberos.EnableWindow( TRUE );
  310. //
  311. // Make sure we're not dealing with a non-Whistler Cluster. If we are then
  312. // disable both checkboxes (the props didn't exist back then - don't set them).
  313. //
  314. CheckForDownlevelCluster();
  315. // If this is a core resource, set the name control to be read-only
  316. // and enable the Core Resource static control.
  317. if (BCore())
  318. {
  319. WINDOWPLACEMENT wpLabel;
  320. WINDOWPLACEMENT wpName;
  321. WINDOWPLACEMENT wpButton;
  322. WINDOWPLACEMENT wpText;
  323. WINDOWPLACEMENT wpCheckDNS;
  324. WINDOWPLACEMENT wpCheckKerberos;
  325. CRect rectName;
  326. CRect rectText;
  327. RECT * prect;
  328. LONG nHeight;
  329. // Get the placement of the controls.
  330. m_editName.GetWindowPlacement(&wpName);
  331. m_staticCore.GetWindowPlacement(&wpText);
  332. m_staticName.GetWindowPlacement(&wpLabel);
  333. m_pbRename.GetWindowPlacement(&wpButton);
  334. m_cbRequireDNS.GetWindowPlacement(&wpCheckDNS);
  335. m_cbRequireKerberos.GetWindowPlacement(&wpCheckKerberos);
  336. // Get the positions of the edit control and text control.
  337. rectName = wpName.rcNormalPosition;
  338. rectText = wpText.rcNormalPosition;
  339. // Move the name control to where the text control is.
  340. prect = &wpName.rcNormalPosition;
  341. *prect = rectText;
  342. nHeight = rectName.bottom - rectName.top;
  343. prect->left = rectName.left;
  344. prect->right = rectName.right;
  345. prect->bottom = prect->top + nHeight;
  346. m_editName.SetWindowPlacement(&wpName);
  347. // Move the text control to where the name control was.
  348. prect = &wpText.rcNormalPosition;
  349. *prect = rectName;
  350. nHeight = rectText.bottom - rectText.top;
  351. prect->left = rectText.left;
  352. prect->right = rectText.right;
  353. prect->bottom = prect->top + nHeight;
  354. m_staticCore.SetWindowPlacement(&wpText);
  355. // Move the name label control to be next to the name edit control.
  356. prect = &wpLabel.rcNormalPosition;
  357. nHeight = prect->bottom - prect->top;
  358. prect->top = wpName.rcNormalPosition.top + 2;
  359. prect->bottom = prect->top + nHeight;
  360. m_staticName.SetWindowPlacement(&wpLabel);
  361. // Move the button control to be next to the name edit control.
  362. prect = &wpButton.rcNormalPosition;
  363. nHeight = prect->bottom - prect->top;
  364. prect->top = wpName.rcNormalPosition.top;
  365. prect->bottom = prect->top + nHeight;
  366. m_pbRename.SetWindowPlacement(&wpButton);
  367. // Move the Require DNS checkbox down.
  368. prect = &wpCheckDNS.rcNormalPosition;
  369. nHeight = prect->bottom - prect->top;
  370. // Move us down by the height of the now displayed static text.
  371. prect->top = prect->top + (wpText.rcNormalPosition.bottom - wpText.rcNormalPosition.top);
  372. prect->top = prect->top + rectText.top - rectName.bottom;
  373. prect->bottom = prect->top + nHeight;
  374. m_cbRequireDNS.SetWindowPlacement(&wpCheckDNS);
  375. // Move the Require Kerberos checkbox down.
  376. prect = &wpCheckKerberos.rcNormalPosition;
  377. nHeight = prect->bottom - prect->top;
  378. // Move us down by the height of the now displayed static text.
  379. prect->top = prect->top + (wpText.rcNormalPosition.bottom - wpText.rcNormalPosition.top);
  380. prect->top = prect->top + rectText.top - rectName.bottom;
  381. prect->bottom = prect->top + nHeight;
  382. m_cbRequireKerberos.SetWindowPlacement(&wpCheckKerberos);
  383. // Prevent the name edit control from being editable and
  384. // Show the text and the button.
  385. m_editName.SetReadOnly(TRUE);
  386. m_staticCore.ShowWindow(SW_SHOW);
  387. m_pbRename.ShowWindow(SW_SHOW);
  388. m_pbRename.EnableWindow( TRUE );
  389. }
  390. else // if: core resource (show static text & move other controls down)
  391. {
  392. m_editName.SetReadOnly(FALSE);
  393. m_staticCore.ShowWindow(SW_HIDE);
  394. m_pbRename.ShowWindow(SW_HIDE);
  395. m_pbRename.EnableWindow( FALSE );
  396. } // else: not core resource
  397. return TRUE; // return TRUE unless you set the focus to a control
  398. // EXCEPTION: OCX Property Pages should return FALSE
  399. } //*** CNetworkNameParamsPage::OnInitDialog()
  400. /////////////////////////////////////////////////////////////////////////////
  401. //++
  402. //
  403. // CNetworkNameParamsPage::OnSetActive
  404. //
  405. // Routine Description:
  406. // Handler for the PSN_SETACTIVE message.
  407. //
  408. // Arguments:
  409. // None.
  410. //
  411. // Return Value:
  412. // TRUE Page successfully initialized.
  413. // FALSE Page not initialized.
  414. //
  415. //--
  416. /////////////////////////////////////////////////////////////////////////////
  417. BOOL CNetworkNameParamsPage::OnSetActive(void)
  418. {
  419. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  420. // Enable/disable the Next/Finish button.
  421. if (BWizard())
  422. {
  423. if (m_strName.GetLength() == 0)
  424. EnableNext(FALSE);
  425. else
  426. EnableNext(TRUE);
  427. } // if: enable/disable the Next button
  428. return CBasePropertyPage::OnSetActive();
  429. } //*** CNetworkNameParamsPage::OnSetActive()
  430. /////////////////////////////////////////////////////////////////////////////
  431. //++
  432. //
  433. // CNetworkNameParamsPage::BApplyChanges
  434. //
  435. // Routine Description:
  436. // Apply changes made on the page.
  437. //
  438. // Arguments:
  439. // None.
  440. //
  441. // Return Value:
  442. // TRUE Page successfully applied.
  443. // FALSE Error applying page.
  444. //
  445. //--
  446. /////////////////////////////////////////////////////////////////////////////
  447. BOOL CNetworkNameParamsPage::BApplyChanges(void)
  448. {
  449. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  450. CWaitCursor wc;
  451. BOOL bSuccess = TRUE;
  452. // Save data.
  453. if (BCore())
  454. {
  455. DWORD scStatus;
  456. //
  457. // If this is the core Network Name (Cluster Name) we should set the name via
  458. // the SetClusterName API. If that succeeds then we'll set the other properties.
  459. //
  460. if ( m_strName != m_strPrevName )
  461. {
  462. scStatus = SetClusterName(Hcluster(), m_strName);
  463. if (scStatus != ERROR_SUCCESS)
  464. {
  465. if (scStatus == ERROR_RESOURCE_PROPERTIES_STORED)
  466. {
  467. TCHAR szError[1024];
  468. CNTException nte(scStatus, NULL, m_strName, NULL, FALSE /*bAutoDelete*/);
  469. nte.FormatErrorMessage(szError, sizeof(szError) / sizeof(TCHAR), NULL, FALSE /*bIncludeID*/);
  470. nte.Delete();
  471. AfxMessageBox(szError);
  472. } // if: properties stored
  473. else
  474. {
  475. CNTException nte(scStatus, IDS_ERROR_SETTING_CLUSTER_NAME, m_strName, NULL, FALSE /*bAutoDelete*/);
  476. nte.ReportError();
  477. nte.Delete();
  478. bSuccess = FALSE;
  479. } // else: other error occurred
  480. } // if: error setting the cluster name
  481. if ( bSuccess )
  482. {
  483. //
  484. // By setting the prev value equal to the current value the BSetPrivateProps
  485. // function will skip this prop when constructing it's list of props to set.
  486. //
  487. m_strPrevName = m_strName;
  488. }
  489. } // if: name has changed
  490. //
  491. // Now set the other private properties.
  492. //
  493. if ( bSuccess == TRUE )
  494. {
  495. bSuccess = BSetPrivateProps();
  496. }
  497. } // if: core resource
  498. else
  499. {
  500. bSuccess = BSetPrivateProps();
  501. }
  502. //
  503. // If we applied the changes then clear the require kerberos check if
  504. // the checkbox was disabled. Don't make this dependent upon the require
  505. // DNS checkbox state as the dependency may change in the future.
  506. //
  507. if( ( bSuccess == TRUE ) &&
  508. ( m_cbRequireKerberos.IsWindowEnabled() == FALSE ) )
  509. {
  510. m_cbRequireKerberos.SetCheck( BST_UNCHECKED );
  511. }
  512. return bSuccess;
  513. } //*** CNetworkNameParamsPage::BApplyChanges()
  514. /////////////////////////////////////////////////////////////////////////////
  515. //++
  516. //
  517. // CNetworkNameParamsPage::OnChangeName
  518. //
  519. // Routine Description:
  520. // Handler for the EN_CHANGE message on the Name edit control.
  521. //
  522. // Arguments:
  523. // None.
  524. //
  525. // Return Value:
  526. // None.
  527. //
  528. //--
  529. /////////////////////////////////////////////////////////////////////////////
  530. void CNetworkNameParamsPage::OnChangeName(void)
  531. {
  532. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  533. OnChangeCtrl();
  534. if (BWizard())
  535. {
  536. if (m_editName.GetWindowTextLength() == 0)
  537. {
  538. EnableNext(FALSE);
  539. }
  540. else
  541. {
  542. EnableNext(TRUE);
  543. }
  544. } // if: in a wizard
  545. } //*** CNetworkNameParamsPage::OnChangeName()
  546. /////////////////////////////////////////////////////////////////////////////
  547. //++
  548. //
  549. // CNetworkNameParamsPage::OnRename
  550. //
  551. // Routine Description:
  552. // Handler for the BN_CLICKED message on the Rename push button.
  553. //
  554. // Arguments:
  555. // None.
  556. //
  557. // Return Value:
  558. // None.
  559. //
  560. //--
  561. /////////////////////////////////////////////////////////////////////////////
  562. void CNetworkNameParamsPage::OnRename(void)
  563. {
  564. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  565. CChangeClusterNameDlg dlg(this);
  566. ASSERT(BCore());
  567. dlg.m_strClusName = m_strName;
  568. if (dlg.DoModal() == IDOK)
  569. {
  570. if (m_strName != dlg.m_strClusName)
  571. {
  572. OnChangeCtrl();
  573. m_strName = dlg.m_strClusName;
  574. UpdateData(FALSE /*bSaveAndValidate*/);
  575. } // if: the name changed
  576. } // if: user accepted change
  577. } //*** CNetworkNameParamsPage::OnRename()
  578. /////////////////////////////////////////////////////////////////////////////
  579. //++
  580. //
  581. // CNetworkNameParamsPage::CheckForDownlevelCluster
  582. //
  583. // Routine Description:
  584. // If determine whether the cluster we're connected to is pre-Whistler.
  585. // If it is then disable the buttons. If an error occurs display a
  586. // message box.
  587. //
  588. // Arguments:
  589. // None.
  590. //
  591. // Return Value:
  592. // None.
  593. //
  594. //--
  595. /////////////////////////////////////////////////////////////////////////////
  596. void CNetworkNameParamsPage::CheckForDownlevelCluster(void)
  597. {
  598. CLUSTERVERSIONINFO cvi;
  599. DWORD sc;
  600. DWORD scErr;
  601. DWORD cchName;
  602. //
  603. // Determine whether we're talking to a pre-Whistler cluster.
  604. // If so, disable the Require DNS & Kerberos checkboxes.
  605. //
  606. memset( &cvi, 0, sizeof( cvi ) );
  607. cvi.dwVersionInfoSize = sizeof( cvi );
  608. cchName = 0;
  609. sc = GetClusterInformation( Hcluster(), NULL, &cchName, &cvi );
  610. scErr = GetLastError();
  611. if( ERROR_SUCCESS != sc )
  612. {
  613. //
  614. // API failed. Pop up a message box.
  615. //
  616. TCHAR szError[1024];
  617. CNTException nte(scErr, IDS_ERROR_GETTING_CLUSTER_INFORMATION, m_strName, NULL, FALSE /*bAutoDelete*/);
  618. nte.FormatErrorMessage(szError, sizeof(szError) / sizeof(TCHAR), NULL, FALSE /*bIncludeID*/);
  619. nte.ReportError();
  620. nte.Delete();
  621. //
  622. // We can't be sure that we're on a down-level cluster (chances are that we're not),
  623. // so leave the checkboxes enabled - the worst that will happen is that some extra props
  624. // will be added that are ignored by the resource.
  625. //
  626. }
  627. else
  628. {
  629. if( CLUSTER_GET_MAJOR_VERSION( cvi.dwClusterHighestVersion ) < NT5_MAJOR_VERSION ) // Less than Win2k.
  630. {
  631. //
  632. // We're on a pre-Win2k Cluster where the DNS & Kerberos setting make no
  633. // sense. So, disable the checkboxes to indicate that the settings
  634. // are unavailable. We'd like to only enable these on Win2k SP3 and later,
  635. // but there's no reliable way to determine SP levels in the cluster (nodes
  636. // may be down).
  637. //
  638. m_cbRequireKerberos.EnableWindow( FALSE );
  639. m_cbRequireDNS.EnableWindow( FALSE );
  640. }
  641. }
  642. } //*** CNetworkNameParamsPage::CheckForDownlevelCluster()