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.

767 lines
18 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // SelNodesPage.cpp
  7. //
  8. // Maintained By:
  9. // David Potter (DavidP) 31-JAN-2001
  10. // Geoffrey Pease (GPease) 12-MAY-2000
  11. //
  12. //////////////////////////////////////////////////////////////////////////////
  13. #include "Pch.h"
  14. #include "SelNodesPage.h"
  15. #include "WizardUtils.h"
  16. #include "Nameutil.h"
  17. #include "AdvancedDlg.h"
  18. #include "DelimitedIterator.h"
  19. DEFINE_THISCLASS("CSelNodesPage");
  20. //////////////////////////////////////////////////////////////////////////////
  21. //++
  22. //
  23. // CSelNodesPage::CSelNodesPage
  24. //
  25. // Description:
  26. // Constructor.
  27. //
  28. // Arguments:
  29. // pccwIn - CClusCfgWizard
  30. //
  31. // Return Values:
  32. // None.
  33. //
  34. //--
  35. //////////////////////////////////////////////////////////////////////////////
  36. CSelNodesPage::CSelNodesPage(
  37. CClusCfgWizard * pccwIn
  38. )
  39. : m_hwnd( NULL )
  40. , m_pccw( pccwIn )
  41. {
  42. TraceFunc( "" );
  43. Assert( pccwIn != NULL );
  44. m_pccw->AddRef();
  45. TraceFuncExit();
  46. } //*** CSelNodesPage::CSelNodesPage
  47. //////////////////////////////////////////////////////////////////////////////
  48. //++
  49. //
  50. // CSelNodesPage::~CSelNodesPage
  51. //
  52. // Description:
  53. // Destructor.
  54. //
  55. // Arguments:
  56. // None.
  57. //
  58. // Return Values:
  59. // None.
  60. //
  61. //--
  62. //////////////////////////////////////////////////////////////////////////////
  63. CSelNodesPage::~CSelNodesPage( void )
  64. {
  65. TraceFunc( "" );
  66. if ( m_pccw != NULL )
  67. {
  68. m_pccw->Release();
  69. }
  70. TraceFuncExit();
  71. } //*** CSelNodesPage::~CSelNodesPage
  72. //////////////////////////////////////////////////////////////////////////////
  73. //++
  74. //
  75. // CSelNodesPage::OnInitDialog
  76. //
  77. // Description:
  78. // Handle the WM_INITDIALOG window message.
  79. //
  80. // Arguments:
  81. // hDlgIn
  82. //
  83. // Return Values:
  84. // FALSE - Didn't set the focus.
  85. //
  86. //-
  87. //////////////////////////////////////////////////////////////////////////////
  88. LRESULT
  89. CSelNodesPage::OnInitDialog(
  90. HWND hDlgIn
  91. )
  92. {
  93. TraceFunc( "" );
  94. LRESULT lr = FALSE; // Didn't set the focus.
  95. //
  96. // Call the base class function.
  97. // This must be called before any other base class methods are called.
  98. //
  99. CSelNodesPageCommon::OnInitDialog( hDlgIn, m_pccw );
  100. RETURN( lr );
  101. } //*** CSelNodesPage::OnInitDialog
  102. //////////////////////////////////////////////////////////////////////////////
  103. //++
  104. //
  105. // CSelNodesPage::OnCommand
  106. //
  107. // Description:
  108. //
  109. // Arguments:
  110. // idNotificationIn
  111. // idControlIn
  112. // hwndSenderIn
  113. //
  114. // Return Values:
  115. // TRUE
  116. // FALSE
  117. //
  118. //--
  119. //////////////////////////////////////////////////////////////////////////////
  120. LRESULT
  121. CSelNodesPage::OnCommand(
  122. UINT idNotificationIn,
  123. UINT idControlIn,
  124. HWND hwndSenderIn
  125. )
  126. {
  127. TraceFunc( "" );
  128. LRESULT lr = FALSE;
  129. switch ( idControlIn )
  130. {
  131. case IDC_SELNODE_E_COMPUTERNAME:
  132. if ( idNotificationIn == EN_CHANGE )
  133. {
  134. THR( HrUpdateWizardButtons() );
  135. lr = TRUE;
  136. }
  137. break;
  138. case IDC_SELNODE_LB_NODES:
  139. if ( idNotificationIn == LBN_SELCHANGE )
  140. {
  141. THR( HrUpdateWizardButtons() );
  142. lr = TRUE;
  143. }
  144. break;
  145. case IDC_SELNODE_PB_BROWSE:
  146. if ( idNotificationIn == BN_CLICKED )
  147. {
  148. THR( HrBrowse( true /* fMultipleNodesIn */ ) );
  149. lr = TRUE;
  150. }
  151. break;
  152. case IDC_SELNODE_PB_ADD:
  153. if ( idNotificationIn == BN_CLICKED )
  154. {
  155. THR( HrAddNodeToList() );
  156. lr = TRUE;
  157. }
  158. break;
  159. case IDC_SELNODE_PB_REMOVE:
  160. if ( idNotificationIn == BN_CLICKED )
  161. {
  162. THR( HrRemoveNodeFromList() );
  163. lr = TRUE;
  164. }
  165. break;
  166. case IDC_SELNODE_PB_ADVANCED:
  167. if ( idNotificationIn == BN_CLICKED )
  168. {
  169. HRESULT hr;
  170. hr = STHR( CAdvancedDlg::S_HrDisplayModalDialog( m_hwnd, m_pccw ) );
  171. if ( hr == S_OK )
  172. {
  173. OnNotifySetActive();
  174. } // if:
  175. lr = TRUE;
  176. } // if:
  177. break;
  178. } // switch: idControlIn
  179. RETURN( lr );
  180. } //*** CSelNodesPage::OnCommand
  181. //////////////////////////////////////////////////////////////////////////////
  182. //++
  183. //
  184. // CSelNodesPage::HrUpdateWizardButtons
  185. //
  186. // Description:
  187. //
  188. // Arguments:
  189. // fSetActiveIn - TRUE = called while handling PSN_SETACTIVE.
  190. //
  191. // Return Values:
  192. // S_OK
  193. //
  194. //--
  195. //////////////////////////////////////////////////////////////////////////////
  196. HRESULT
  197. CSelNodesPage::HrUpdateWizardButtons(
  198. bool fSetActiveIn // = false
  199. )
  200. {
  201. TraceFunc( "" );
  202. HRESULT hr = S_OK;
  203. HWND hwndList = GetDlgItem( m_hwnd, IDC_SELNODE_LB_NODES );
  204. DWORD dwFlags = PSWIZB_BACK | PSWIZB_NEXT;
  205. DWORD dwLen;
  206. LRESULT lr;
  207. // Disable the Next button if there are no entries in the list box
  208. // or if the edit control is not empty.
  209. lr = ListBox_GetCount( hwndList );
  210. dwLen = GetWindowTextLength( GetDlgItem( m_hwnd, IDC_SELNODE_E_COMPUTERNAME ) );
  211. if ( ( lr == 0 )
  212. || ( dwLen != 0 ) )
  213. {
  214. dwFlags &= ~PSWIZB_NEXT;
  215. }
  216. // This cannot be done synchronously if called while handling
  217. // PSN_SETACTIVE. Otherwise, do it synchronously.
  218. if ( fSetActiveIn )
  219. {
  220. PropSheet_SetWizButtons( GetParent( m_hwnd ), dwFlags );
  221. }
  222. else
  223. {
  224. SendMessage( GetParent( m_hwnd ), PSM_SETWIZBUTTONS, 0, (LPARAM) dwFlags );
  225. }
  226. // Enable or disable the Add button based on whether there is text
  227. // in the edit control or not.
  228. if ( dwLen == 0 )
  229. {
  230. EnableWindow( GetDlgItem( m_hwnd, IDC_SELNODE_PB_ADD ), FALSE );
  231. }
  232. else
  233. {
  234. EnableWindow( GetDlgItem( m_hwnd, IDC_SELNODE_PB_ADD ), TRUE );
  235. SendMessage( m_hwnd, DM_SETDEFID, IDC_SELNODE_PB_ADD, 0 );
  236. }
  237. // Enable or disable the Remove button based whether an item is
  238. // selected in the list box or not.
  239. lr = ListBox_GetCurSel( hwndList );
  240. if ( lr == LB_ERR )
  241. {
  242. EnableWindow( GetDlgItem( m_hwnd, IDC_SELNODE_PB_REMOVE ), FALSE );
  243. }
  244. else
  245. {
  246. EnableWindow( GetDlgItem( m_hwnd, IDC_SELNODE_PB_REMOVE ), TRUE );
  247. }
  248. HRETURN( hr );
  249. } //*** CSelNodesPage::HrUpdateWizardButtons
  250. //////////////////////////////////////////////////////////////////////////////
  251. //++
  252. //
  253. // CSelNodesPage::HrAddNodeToList
  254. //
  255. // Description:
  256. //
  257. // Arguments:
  258. // None.
  259. //
  260. // Return Values:
  261. // S_OK
  262. // E_OUTOFMEMORY
  263. //
  264. //--
  265. //////////////////////////////////////////////////////////////////////////////
  266. HRESULT
  267. CSelNodesPage::HrAddNodeToList( void )
  268. {
  269. TraceFunc( "" );
  270. HRESULT hr = S_OK;
  271. DWORD dwLen = 0;
  272. int idcFocus = 0;
  273. BSTR bstrErrorMessage = NULL;
  274. BSTR bstrErrorTitle = NULL;
  275. LPWSTR pszComputerList = NULL;
  276. dwLen = GetWindowTextLength( GetDlgItem( m_hwnd, IDC_SELNODE_E_COMPUTERNAME ) );
  277. if ( dwLen == 0 )
  278. {
  279. hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
  280. if ( hr == HRESULT_FROM_WIN32( ERROR_SUCCESS ) )
  281. {
  282. AssertMsg( dwLen != 0, "How did we get here?!" );
  283. }
  284. goto Error;
  285. }
  286. pszComputerList = new WCHAR[ dwLen + 1 ];
  287. if ( pszComputerList == NULL )
  288. {
  289. hr = THR( E_OUTOFMEMORY );
  290. goto Error;
  291. }
  292. dwLen = GetDlgItemText( m_hwnd, IDC_SELNODE_E_COMPUTERNAME, pszComputerList, dwLen + 1 );
  293. AssertMsg( dwLen != 0, "How did we get here?!" );
  294. //
  295. // Validate each computer name entered.
  296. //
  297. {
  298. CDelimitedIterator it( L",; ", pszComputerList, dwLen );
  299. while ( it.Current() != NULL )
  300. {
  301. int dwIndex = ListBox_FindStringExact(
  302. GetDlgItem( m_hwnd, IDC_SELNODE_LB_NODES ),
  303. -1, it.Current()); // case insensitive search
  304. // add the string only if it is not already there
  305. if ( dwIndex == LB_ERR )
  306. {
  307. hr = THR( HrValidateFQNPrefix( it.Current() ) );
  308. if ( FAILED( hr ) )
  309. {
  310. THR( HrShowInvalidLabelPrompt( m_hwnd, it.Current(), hr ) );
  311. idcFocus = IDC_SELNODE_E_COMPUTERNAME;
  312. goto Error;
  313. }
  314. hr = STHR( m_pccw->HrAddNode( it.Current(), true /*accept non-RFC characters*/ ) );
  315. if ( FAILED( hr ) )
  316. {
  317. goto Error;
  318. }
  319. if ( hr == S_OK )
  320. {
  321. ListBox_AddString( GetDlgItem( m_hwnd, IDC_SELNODE_LB_NODES ), it.Current() );
  322. }
  323. else if ( hr == S_FALSE )
  324. {
  325. hr = THR( HrFormatStringIntoBSTR( g_hInstance, IDS_ERR_DUPLICATE_NODE_TEXT, &bstrErrorMessage, it.Current() ) );
  326. if ( FAILED( hr ) )
  327. {
  328. goto Error;
  329. }
  330. hr = THR( HrFormatStringIntoBSTR( g_hInstance, IDS_ERR_DUPLICATE_NODE_TITLE, &bstrErrorTitle ) );
  331. if ( FAILED( hr ) )
  332. {
  333. goto Error;
  334. }
  335. MessageBox( m_hwnd, bstrErrorTitle, bstrErrorMessage, MB_OK | MB_ICONSTOP );
  336. TraceSysFreeString( bstrErrorTitle );
  337. bstrErrorTitle = NULL;
  338. TraceSysFreeString( bstrErrorMessage );
  339. bstrErrorMessage = NULL;
  340. }
  341. }
  342. it.Next();
  343. } // for each computer name entered
  344. } // validating each computer name
  345. SetDlgItemText( m_hwnd, IDC_SELNODE_E_COMPUTERNAME, L"" );
  346. hr = THR( HrUpdateWizardButtons() );
  347. goto Cleanup;
  348. Error:
  349. if ( idcFocus != 0 )
  350. {
  351. SetFocus( GetDlgItem( m_hwnd, idcFocus ) );
  352. }
  353. goto Cleanup;
  354. Cleanup:
  355. if ( pszComputerList != NULL )
  356. {
  357. delete[] pszComputerList;
  358. }
  359. TraceSysFreeString( bstrErrorMessage );
  360. TraceSysFreeString( bstrErrorTitle );
  361. HRETURN( hr );
  362. } //*** CSelNodesPage::HrAddNodeToList
  363. //////////////////////////////////////////////////////////////////////////////
  364. //++
  365. //
  366. // CSelNodesPage::HrRemoveNodeFromList
  367. //
  368. // Description:
  369. //
  370. // Arguments:
  371. // None.
  372. //
  373. // Return Values:
  374. // S_OK
  375. //
  376. //--
  377. //////////////////////////////////////////////////////////////////////////////
  378. HRESULT
  379. CSelNodesPage::HrRemoveNodeFromList( void )
  380. {
  381. TraceFunc( "" );
  382. HRESULT hr = S_OK;
  383. BSTR bstrNodeName = NULL;
  384. HWND hwndList;
  385. LRESULT lr;
  386. int cchName = 0;
  387. hwndList = GetDlgItem( m_hwnd, IDC_SELNODE_LB_NODES );
  388. lr = ListBox_GetCurSel( hwndList );
  389. if ( lr != LB_ERR )
  390. {
  391. cchName = ListBox_GetTextLen( hwndList, lr );
  392. Assert( cchName != LB_ERR );
  393. cchName++; // Add one for NULL
  394. bstrNodeName = TraceSysAllocStringLen( NULL, cchName );
  395. if( bstrNodeName == NULL )
  396. {
  397. hr = THR( E_OUTOFMEMORY );
  398. goto Cleanup;
  399. }
  400. ListBox_GetText( hwndList, lr, bstrNodeName );
  401. hr = THR( m_pccw->RemoveComputer( bstrNodeName ) );
  402. if ( FAILED( hr ) )
  403. {
  404. goto Cleanup;
  405. }
  406. ListBox_DeleteString( hwndList, lr );
  407. } // if: lr != LB_ERR
  408. hr = THR( HrUpdateWizardButtons() );
  409. Cleanup:
  410. TraceSysFreeString( bstrNodeName );
  411. HRETURN( hr );
  412. } //*** CSelNodesPage::HrRemoveNodeFromList
  413. //////////////////////////////////////////////////////////////////////////////
  414. //++
  415. //
  416. // CSelNodesPage::OnNotifySetActive
  417. //
  418. // Description:
  419. //
  420. // Arguments:
  421. // None.
  422. //
  423. // Return Values:
  424. // TRUE
  425. //
  426. //--
  427. //////////////////////////////////////////////////////////////////////////////
  428. LRESULT
  429. CSelNodesPage::OnNotifySetActive( void )
  430. {
  431. TraceFunc( "" );
  432. LRESULT lr = TRUE;
  433. THR( HrUpdateWizardButtons( true ) );
  434. RETURN( lr );
  435. } //*** CSelNodesPage::OnNotifySetActive
  436. //////////////////////////////////////////////////////////////////////////////
  437. //++
  438. //
  439. // CSelNodesPage::OnNotifyQueryCancel
  440. //
  441. // Description:
  442. //
  443. // Arguments:
  444. // None.
  445. //
  446. // Return Values:
  447. // TRUE
  448. //
  449. //--
  450. //////////////////////////////////////////////////////////////////////////////
  451. LRESULT
  452. CSelNodesPage::OnNotifyQueryCancel( void )
  453. {
  454. TraceFunc( "" );
  455. LRESULT lr = TRUE;
  456. int iRet;
  457. iRet = MessageBoxFromStrings( m_hwnd,
  458. IDS_QUERY_CANCEL_TITLE,
  459. IDS_QUERY_CANCEL_TEXT,
  460. MB_YESNO
  461. );
  462. if ( iRet == IDNO )
  463. {
  464. SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 );
  465. }
  466. RETURN( lr );
  467. } //*** CSelNodesPage::OnNotifyQueryCancel
  468. //////////////////////////////////////////////////////////////////////////////
  469. //++
  470. //
  471. // CSelNodesPage::OnNotifyWizNext
  472. //
  473. // Description:
  474. //
  475. // Arguments:
  476. // None.
  477. //
  478. // Return Values:
  479. // TRUE
  480. // LB_ERR
  481. // Other LRESULT values.
  482. //
  483. //--
  484. //////////////////////////////////////////////////////////////////////////////
  485. LRESULT
  486. CSelNodesPage::OnNotifyWizNext( void )
  487. {
  488. TraceFunc( "" );
  489. LRESULT lr = TRUE;
  490. RETURN( lr );
  491. } //*** CSelNodesPage::OnNotifyWizNext
  492. //////////////////////////////////////////////////////////////////////////////
  493. //++
  494. //
  495. // CSelNodesPage::OnNotify
  496. //
  497. // Description:
  498. //
  499. // Arguments:
  500. // idCtrlIn
  501. // pnmhdrIn
  502. //
  503. // Return Values:
  504. // TRUE
  505. // Other LRESULT values.
  506. //
  507. //--
  508. //////////////////////////////////////////////////////////////////////////////
  509. LRESULT
  510. CSelNodesPage::OnNotify(
  511. WPARAM idCtrlIn,
  512. LPNMHDR pnmhdrIn
  513. )
  514. {
  515. TraceFunc( "" );
  516. LRESULT lr = TRUE;
  517. SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, 0 );
  518. switch( pnmhdrIn->code )
  519. {
  520. case PSN_SETACTIVE:
  521. lr = OnNotifySetActive();
  522. break;
  523. case PSN_WIZNEXT:
  524. lr = OnNotifyWizNext();
  525. break;
  526. case PSN_QUERYCANCEL:
  527. lr = OnNotifyQueryCancel();
  528. break;
  529. } // switch: notification code
  530. RETURN( lr );
  531. } //*** CSelNodesPage::OnNotify
  532. //////////////////////////////////////////////////////////////////////////////
  533. //++
  534. //
  535. // static
  536. // CALLBACK
  537. // CSelNodesPage::S_DlgProc
  538. //
  539. // Description:
  540. // Dialog proc for this page.
  541. //
  542. // Arguments:
  543. // hDlgIn
  544. // MsgIn
  545. // wParam
  546. // lParam
  547. //
  548. // Return Values:
  549. // FALSE
  550. // Other LRESULT values.
  551. //
  552. //--
  553. //////////////////////////////////////////////////////////////////////////////
  554. INT_PTR
  555. CALLBACK
  556. CSelNodesPage::S_DlgProc(
  557. HWND hDlgIn,
  558. UINT MsgIn,
  559. WPARAM wParam,
  560. LPARAM lParam
  561. )
  562. {
  563. // Don't do TraceFunc because every mouse movement
  564. // will cause this function to be called.
  565. WndMsg( hDlgIn, MsgIn, wParam, lParam );
  566. LRESULT lr = FALSE;
  567. CSelNodesPage * pPage = reinterpret_cast< CSelNodesPage *> ( GetWindowLongPtr( hDlgIn, GWLP_USERDATA ) );
  568. if ( MsgIn == WM_INITDIALOG )
  569. {
  570. Assert( lParam != NULL );
  571. PROPSHEETPAGE * ppage = reinterpret_cast< PROPSHEETPAGE * >( lParam );
  572. SetWindowLongPtr( hDlgIn, GWLP_USERDATA, (LPARAM) ppage->lParam );
  573. pPage = reinterpret_cast< CSelNodesPage * >( ppage->lParam );
  574. pPage->m_hwnd = hDlgIn;
  575. }
  576. if ( pPage != NULL )
  577. {
  578. Assert( hDlgIn == pPage->m_hwnd );
  579. switch( MsgIn )
  580. {
  581. case WM_INITDIALOG:
  582. lr = pPage->OnInitDialog( hDlgIn );
  583. break;
  584. case WM_NOTIFY:
  585. lr = pPage->OnNotify( wParam, reinterpret_cast< LPNMHDR >( lParam ) );
  586. break;
  587. case WM_COMMAND:
  588. lr= pPage->OnCommand( HIWORD( wParam ), LOWORD( wParam ), (HWND) lParam );
  589. break;
  590. // no default clause needed
  591. } // switch: message
  592. } // if: there is a page associated with the window
  593. return lr;
  594. } //*** CSelNodesPage::S_DlgProc
  595. //////////////////////////////////////////////////////////////////////////////
  596. //++
  597. //
  598. // CSelNodesPage::OnFilteredNodesWithBadDomains
  599. //
  600. // Description:
  601. //
  602. // Arguments:
  603. // pwcszNodeListIn
  604. //
  605. // Return Values:
  606. // None.
  607. //
  608. //--
  609. //////////////////////////////////////////////////////////////////////////////
  610. void
  611. CSelNodesPage::OnFilteredNodesWithBadDomains( PCWSTR pwcszNodeListIn )
  612. {
  613. SetDlgItemText( m_hwnd, IDC_SELNODE_E_COMPUTERNAME, pwcszNodeListIn );
  614. } //*** CSelNodesPage::OnFilteredNodesWithBadDomains
  615. //////////////////////////////////////////////////////////////////////////////
  616. //++
  617. //
  618. // CSelNodesPage::OnProcessedValidNode
  619. //
  620. // Description:
  621. //
  622. // Arguments:
  623. // pwcszNodeNameIn
  624. //
  625. // Return Values:
  626. // None.
  627. //
  628. //--
  629. //////////////////////////////////////////////////////////////////////////////
  630. void
  631. CSelNodesPage::OnProcessedValidNode( PCWSTR pwcszNodeNameIn )
  632. {
  633. ListBox_AddString( GetDlgItem( m_hwnd, IDC_SELNODE_LB_NODES ), pwcszNodeNameIn );
  634. } //*** CSelNodesPage::OnProcessedValidNode
  635. //////////////////////////////////////////////////////////////////////////////
  636. //++
  637. //
  638. // CSelNodesPage::HrSetDefaultNode
  639. //
  640. // Description:
  641. //
  642. // Arguments:
  643. // pwcszNodeNameIn
  644. //
  645. // Return Values:
  646. // S_OK.
  647. //
  648. //--
  649. //////////////////////////////////////////////////////////////////////////////
  650. HRESULT
  651. CSelNodesPage::HrSetDefaultNode( PCWSTR pwcszNodeNameIn )
  652. {
  653. SetDlgItemText( m_hwnd, IDC_SELNODE_E_COMPUTERNAME, pwcszNodeNameIn );
  654. return S_OK;
  655. } //*** CSelNodesPage::HrSetDefaultNode