Source code of Windows XP (NT5)
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.

790 lines
17 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // SelNodePage.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 "SelNodePage.h"
  15. #include "WizardUtils.h"
  16. DEFINE_THISCLASS("CSelNodePage");
  17. //////////////////////////////////////////////////////////////////////////////
  18. //++
  19. //
  20. // CSelNodePage::CSelNodePage
  21. //
  22. // Description:
  23. // Constructor.
  24. //
  25. // Arguments:
  26. // pspIn -- IServiceProvider
  27. // ecamCreateAddModeIn -- Creating cluster or adding nodes to cluster.
  28. // pcCountInout -- Count of computers in prgbstrComputersInout
  29. // prgbstrComputersInout -- Array of computers
  30. // pbstrClusterNameIn -- Name of the cluster
  31. //
  32. // Return Values:
  33. // None.
  34. //
  35. // Remarks:
  36. //
  37. //--
  38. //////////////////////////////////////////////////////////////////////////////
  39. CSelNodePage::CSelNodePage(
  40. IServiceProvider * pspIn,
  41. ECreateAddMode ecamCreateAddModeIn,
  42. ULONG * pcCountInout,
  43. BSTR ** prgbstrComputersInout,
  44. BSTR * pbstrClusterNameIn
  45. )
  46. {
  47. TraceFunc( "" );
  48. Assert( pspIn != NULL );
  49. Assert( pcCountInout != NULL );
  50. Assert( prgbstrComputersInout != NULL );
  51. Assert( pbstrClusterNameIn != NULL );
  52. // m_hwnd
  53. THR( pspIn->TypeSafeQI( IServiceProvider, &m_psp ) );
  54. m_pcCount = pcCountInout;
  55. m_prgbstrComputerName = prgbstrComputersInout;
  56. m_pbstrClusterName = pbstrClusterNameIn;
  57. m_cfDsObjectPicker = 0;
  58. TraceFuncExit();
  59. } //*** CSelNodePage::CSelNodePage()
  60. //////////////////////////////////////////////////////////////////////////////
  61. //++
  62. //
  63. // CSelNodePage::~CSelNodePage
  64. //
  65. // Description:
  66. // Destructor.
  67. //
  68. // Arguments:
  69. // None.
  70. //
  71. // Return Values:
  72. // None.
  73. //
  74. // Remarks:
  75. //
  76. //--
  77. //////////////////////////////////////////////////////////////////////////////
  78. CSelNodePage::~CSelNodePage( void )
  79. {
  80. TraceFunc( "" );
  81. if ( m_psp != NULL )
  82. {
  83. m_psp->Release();
  84. }
  85. TraceFuncExit();
  86. } //*** CSelNodePage::~CSelNodePage()
  87. //////////////////////////////////////////////////////////////////////////////
  88. //++
  89. //
  90. // CSelNodePage::OnInitDialog
  91. //
  92. // Description:
  93. // Handle the WM_INITDIALOG window message.
  94. //
  95. // Arguments:
  96. // hDlgIn
  97. //
  98. // Return Values:
  99. // FALSE - Didn't set the focus.
  100. //
  101. // Remarks:
  102. //
  103. //--
  104. //////////////////////////////////////////////////////////////////////////////
  105. LRESULT
  106. CSelNodePage::OnInitDialog(
  107. HWND hDlgIn
  108. )
  109. {
  110. TraceFunc( "" );
  111. BSTR bstrComputerName = NULL;
  112. LRESULT lr = FALSE; // Didn't set the focus.
  113. HRESULT hr;
  114. if ( ( *m_prgbstrComputerName != NULL )
  115. && ( *m_pcCount == 1 )
  116. && ( (*m_prgbstrComputerName)[ 0 ] != NULL )
  117. )
  118. {
  119. SetDlgItemText( m_hwnd, IDC_SELNODE_E_COMPUTERNAME, (*m_prgbstrComputerName)[ 0 ] );
  120. }
  121. else
  122. {
  123. DWORD dwStatus;
  124. DWORD dwClusterState;
  125. //
  126. // If the node is already in a cluster, don't have it default in the edit box.
  127. // If there is an error getting the "NodeClusterState", then default the node
  128. // name (it could be in the middle of cleaning up the node).
  129. //
  130. dwStatus = TW32( GetNodeClusterState( NULL, &dwClusterState ) );
  131. if ( ( dwStatus != ERROR_SUCCESS )
  132. || ( dwClusterState == ClusterStateNotConfigured ) )
  133. {
  134. hr = THR( HrGetComputerName( ComputerNameDnsHostname, &bstrComputerName ) );
  135. if ( FAILED( hr ) )
  136. {
  137. goto Cleanup;
  138. }
  139. }
  140. SetDlgItemText( m_hwnd, IDC_SELNODE_E_COMPUTERNAME, bstrComputerName );
  141. } // else: no computer was specified
  142. m_cfDsObjectPicker = RegisterClipboardFormat( CFSTR_DSOP_DS_SELECTION_LIST );
  143. if ( m_cfDsObjectPicker == 0 )
  144. {
  145. DWORD sc;
  146. //
  147. // TODO: 5-JUL-2000 GalenB
  148. //
  149. // Need to log this?
  150. //
  151. sc = TW32( GetLastError() );
  152. EnableWindow( GetDlgItem( hDlgIn, IDC_SELNODE_PB_BROWSE ), FALSE );
  153. } // if:
  154. Cleanup:
  155. TraceSysFreeString( bstrComputerName );
  156. RETURN( lr );
  157. } //*** CSelNodePage::OnInitDialog()
  158. //////////////////////////////////////////////////////////////////////////////
  159. //++
  160. //
  161. // CSelNodePage::OnCommand
  162. //
  163. // Description:
  164. //
  165. // Arguments:
  166. // idNotificationIn
  167. // idControlIn
  168. // hwndSenderIn
  169. //
  170. // Return Values:
  171. // TRUE
  172. // FALSE
  173. //
  174. // Remarks:
  175. //
  176. //--
  177. //////////////////////////////////////////////////////////////////////////////
  178. LRESULT
  179. CSelNodePage::OnCommand(
  180. UINT idNotificationIn,
  181. UINT idControlIn,
  182. HWND hwndSenderIn
  183. )
  184. {
  185. TraceFunc( "" );
  186. LRESULT lr = FALSE;
  187. switch ( idControlIn )
  188. {
  189. case IDC_SELNODE_E_COMPUTERNAME:
  190. if ( idNotificationIn == EN_CHANGE )
  191. {
  192. THR( HrUpdateWizardButtons() );
  193. lr = TRUE;
  194. }
  195. break;
  196. case IDC_SELNODE_PB_BROWSE:
  197. if ( idNotificationIn == BN_CLICKED )
  198. {
  199. //
  200. // TODO: 26-JUN-2000 GalenB
  201. //
  202. // Need to set lr properly.
  203. //
  204. THR( HrBrowse() );
  205. lr = TRUE;
  206. }
  207. break;
  208. } // switch: idControlIn
  209. RETURN( lr );
  210. } //*** CSelNodePage::OnCommand()
  211. //////////////////////////////////////////////////////////////////////////////
  212. //++
  213. //
  214. // CSelNodePage::HrUpdateWizardButtons
  215. //
  216. // Description:
  217. //
  218. // Arguments:
  219. // None.
  220. //
  221. // Return Values:
  222. // S_OK
  223. //
  224. // Remarks:
  225. //
  226. //--
  227. //////////////////////////////////////////////////////////////////////////////
  228. HRESULT
  229. CSelNodePage::HrUpdateWizardButtons( void )
  230. {
  231. TraceFunc( "" );
  232. HRESULT hr = S_OK;
  233. DWORD dwFlags = PSWIZB_BACK | PSWIZB_NEXT;
  234. DWORD dwLen;
  235. dwLen = GetWindowTextLength( GetDlgItem( m_hwnd, IDC_SELNODE_E_COMPUTERNAME ) );
  236. if ( dwLen == 0 )
  237. {
  238. dwFlags &= ~PSWIZB_NEXT;
  239. }
  240. PropSheet_SetWizButtons( GetParent( m_hwnd ), dwFlags );
  241. HRETURN( hr );
  242. } //*** CSelNodePage::HrUpdateWizardButtons()
  243. //////////////////////////////////////////////////////////////////////////////
  244. //++
  245. //
  246. // CSelNodePage::OnNotifySetActive
  247. //
  248. // Description:
  249. //
  250. // Arguments:
  251. // None.
  252. //
  253. // Return Values:
  254. // TRUE
  255. //
  256. // Remarks:
  257. //
  258. //--
  259. //////////////////////////////////////////////////////////////////////////////
  260. LRESULT
  261. CSelNodePage::OnNotifySetActive( void )
  262. {
  263. TraceFunc( "" );
  264. LRESULT lr = TRUE;
  265. THR( HrUpdateWizardButtons() );
  266. //
  267. // TODO: gpease 23-MAY-2000
  268. // Figure out: If the user clicks back and changes the computer
  269. // name, how do we update the middle tier?
  270. //
  271. RETURN( lr );
  272. } //*** CSelNodePage::OnNotifySetActive()
  273. //////////////////////////////////////////////////////////////////////////////
  274. //++
  275. //
  276. // CSelNodePage::OnNotifyQueryCancel
  277. //
  278. // Description:
  279. //
  280. // Arguments:
  281. // None.
  282. //
  283. // Return Values:
  284. // TRUE
  285. //
  286. // Remarks:
  287. //
  288. //--
  289. //////////////////////////////////////////////////////////////////////////////
  290. LRESULT
  291. CSelNodePage::OnNotifyQueryCancel( void )
  292. {
  293. TraceFunc( "" );
  294. LRESULT lr = TRUE;
  295. int iRet;
  296. iRet = MessageBoxFromStrings( m_hwnd,
  297. IDS_QUERY_CANCEL_TITLE,
  298. IDS_QUERY_CANCEL_TEXT,
  299. MB_YESNO
  300. );
  301. if ( iRet == IDNO )
  302. {
  303. SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 );
  304. }
  305. RETURN( lr );
  306. } //*** CSelNodePage::OnNotifyQueryCancel()
  307. //////////////////////////////////////////////////////////////////////////////
  308. //++
  309. //
  310. // CSelNodePage::OnNotifyWizNext
  311. //
  312. // Description:
  313. //
  314. // Arguments:
  315. // None.
  316. //
  317. // Return Values:
  318. // TRUE
  319. // Other LRESULT values.
  320. //
  321. // Remarks:
  322. //
  323. //--
  324. //////////////////////////////////////////////////////////////////////////////
  325. LRESULT
  326. CSelNodePage::OnNotifyWizNext( void )
  327. {
  328. TraceFunc( "" );
  329. HRESULT hr;
  330. LPWSTR pszDomain;
  331. DWORD dwLen;
  332. DNS_STATUS dnsStatus;
  333. BSTR bstrComputerName;
  334. int idcFocus = 0;
  335. OBJECTCOOKIE cookieDummy;
  336. OBJECTCOOKIE cookieCluster;
  337. WCHAR szComputerName[ DNS_MAX_NAME_BUFFER_LENGTH ] = { 0 };
  338. LRESULT lr = TRUE;
  339. dwLen = GetDlgItemText( m_hwnd, IDC_SELNODE_E_COMPUTERNAME, szComputerName, ARRAYSIZE( szComputerName ) );
  340. AssertMsg( dwLen != 0, "How did I get here?" );
  341. hr = THR( HrValidateDnsHostname( m_hwnd, szComputerName, mvdhoALLOW_ONLY_HOSTNAME_LABEL ) );
  342. if ( FAILED( hr ) )
  343. {
  344. idcFocus = IDC_SELNODE_E_COMPUTERNAME;
  345. goto Error;
  346. }
  347. //
  348. // Build the FQDN DNS hostname to the computer.
  349. //
  350. pszDomain = wcschr( *m_pbstrClusterName, L'.' );
  351. Assert( pszDomain != NULL );
  352. if ( pszDomain == NULL )
  353. {
  354. // BUGBUG 31-JAN-2001 DavidP What can the user do here? We need a better way to handle this.
  355. goto Cleanup;
  356. }
  357. wcsncpy( &szComputerName[ dwLen ], pszDomain, ARRAYSIZE( szComputerName ) - dwLen - 1 /* NULL */ );
  358. bstrComputerName = TraceSysAllocString( szComputerName );
  359. if ( bstrComputerName == NULL )
  360. {
  361. goto OutOfMemory;
  362. }
  363. //
  364. // Free old list (if any)
  365. //
  366. while ( *m_pcCount != 0 )
  367. {
  368. (*m_pcCount) --;
  369. TraceSysFreeString( (*m_prgbstrComputerName)[ *m_pcCount ] );
  370. }
  371. //
  372. // Make a new list (if needed).
  373. //
  374. if ( *m_prgbstrComputerName == NULL )
  375. {
  376. *m_prgbstrComputerName = (BSTR *) TraceAlloc( 0, sizeof(BSTR) );
  377. if ( *m_prgbstrComputerName == NULL )
  378. {
  379. goto OutOfMemory;
  380. }
  381. }
  382. //
  383. // Take ownership of bstrComputerName.
  384. //
  385. *m_pcCount = 1;
  386. (*m_prgbstrComputerName)[ 0 ] = bstrComputerName;
  387. Cleanup:
  388. RETURN( lr );
  389. Error:
  390. if ( idcFocus != 0 )
  391. {
  392. SetFocus( GetDlgItem( m_hwnd, idcFocus ) );
  393. }
  394. // Don't go to the next page.
  395. SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 );
  396. goto Cleanup;
  397. OutOfMemory:
  398. goto Error;
  399. } //*** CSelNodePage::OnNotifyWizNext()
  400. //////////////////////////////////////////////////////////////////////////////
  401. //++
  402. //
  403. // CSelNodePage::OnNotify
  404. //
  405. // Description:
  406. //
  407. // Arguments:
  408. // idCtrlIn
  409. // pnmhdrIn
  410. //
  411. // Return Values:
  412. // TRUE
  413. // Other LRESULT values
  414. //
  415. // Remarks:
  416. //
  417. //--
  418. //////////////////////////////////////////////////////////////////////////////
  419. LRESULT
  420. CSelNodePage::OnNotify(
  421. WPARAM idCtrlIn,
  422. LPNMHDR pnmhdrIn
  423. )
  424. {
  425. TraceFunc( "" );
  426. LRESULT lr = TRUE;
  427. SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, 0 );
  428. switch( pnmhdrIn->code )
  429. {
  430. case PSN_SETACTIVE:
  431. lr = OnNotifySetActive();
  432. break;
  433. case PSN_WIZNEXT:
  434. lr = OnNotifyWizNext();
  435. break;
  436. case PSN_QUERYCANCEL:
  437. lr = OnNotifyQueryCancel();
  438. break;
  439. } // switch: notify code
  440. RETURN( lr );
  441. } //*** CSelNodePage::OnNotify()
  442. //////////////////////////////////////////////////////////////////////////////
  443. //++
  444. //
  445. // CSelNodePage::HrBrowse
  446. //
  447. // Description:
  448. //
  449. // Arguments:
  450. // None.
  451. //
  452. // Return Values:
  453. // S_OK
  454. // Other HRESULT values.
  455. //
  456. // Remarks:
  457. //
  458. //--
  459. //////////////////////////////////////////////////////////////////////////////
  460. HRESULT
  461. CSelNodePage::HrBrowse( void )
  462. {
  463. TraceFunc( "" );
  464. HRESULT hr = S_OK;
  465. IDsObjectPicker * piop = NULL;
  466. IDataObject * pido = NULL;
  467. HCURSOR hOldCursor = NULL;
  468. hOldCursor = SetCursor( LoadCursor( g_hInstance, IDC_WAIT ) );
  469. // Create an instance of the object picker.
  470. hr = THR( CoCreateInstance( CLSID_DsObjectPicker, NULL, CLSCTX_INPROC_SERVER, IID_IDsObjectPicker, (void **) &piop ) );
  471. if ( FAILED( hr ) )
  472. {
  473. goto CleanUp;
  474. } // if:
  475. // Initialize the object picker instance.
  476. hr = THR( HrInitObjectPicker( piop ) );
  477. if ( FAILED( hr ) )
  478. {
  479. goto CleanUp;
  480. } // if:
  481. SetCursor( hOldCursor );
  482. // Invoke the modal dialog.
  483. hr = THR( piop->InvokeDialog( m_hwnd, &pido ) );
  484. if ( FAILED( hr ) )
  485. {
  486. goto CleanUp;
  487. } // if:
  488. if ( hr == S_OK )
  489. {
  490. hr = THR( HrGetSelection( pido ) );
  491. } // if:
  492. else if ( hr == S_FALSE )
  493. {
  494. hr = S_OK; // don't want to squawk in the caller...
  495. } // else if:
  496. CleanUp:
  497. if ( pido != NULL )
  498. {
  499. pido->Release();
  500. } // if:
  501. if ( piop != NULL )
  502. {
  503. piop->Release();
  504. } // if:
  505. HRETURN( hr );
  506. } //*** CSelNodePage::HrBrowse()
  507. //////////////////////////////////////////////////////////////////////////////
  508. //++
  509. //
  510. // CSelNodePage::HrInitObjectPicker
  511. //
  512. // Description:
  513. //
  514. // Arguments:
  515. // piopIn -- IDsObjectPicker
  516. //
  517. // Return Values:
  518. // HRESULT values.
  519. //
  520. // Remarks:
  521. //
  522. //--
  523. //////////////////////////////////////////////////////////////////////////////
  524. HRESULT
  525. CSelNodePage::HrInitObjectPicker( IDsObjectPicker * piopIn )
  526. {
  527. TraceFunc( "" );
  528. DSOP_SCOPE_INIT_INFO rgScopeInit[ 1 ];
  529. DSOP_INIT_INFO iiInfo;
  530. ZeroMemory( rgScopeInit, sizeof( DSOP_SCOPE_INIT_INFO ) * (sizeof( rgScopeInit ) / sizeof( rgScopeInit[ 0 ] ) ) );
  531. rgScopeInit[ 0 ].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  532. rgScopeInit[ 0 ].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  533. rgScopeInit[ 0 ].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
  534. rgScopeInit[ 0 ].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_COMPUTERS;
  535. rgScopeInit[ 0 ].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  536. ZeroMemory( &iiInfo, sizeof( iiInfo ) );
  537. iiInfo.cbSize = sizeof( iiInfo );
  538. iiInfo.pwzTargetComputer = NULL;
  539. iiInfo.cDsScopeInfos = 1;
  540. iiInfo.aDsScopeInfos = rgScopeInit;
  541. iiInfo.flOptions = 0; //DSOP_FLAG_MULTISELECT;
  542. HRETURN( piopIn->Initialize( &iiInfo) );
  543. } //*** CSelNodePage::HrInitObjectPicker
  544. //////////////////////////////////////////////////////////////////////////////
  545. //++
  546. //
  547. // CSelNodePage::HrGetSelection
  548. //
  549. // Description:
  550. //
  551. // Arguments:
  552. // pidoIn -- IDataObject
  553. //
  554. // Return Values:
  555. // HRESULT values.
  556. //
  557. // Remarks:
  558. //
  559. //--
  560. //////////////////////////////////////////////////////////////////////////////
  561. HRESULT
  562. CSelNodePage::HrGetSelection(
  563. IDataObject * pidoIn
  564. )
  565. {
  566. TraceFunc( "" );
  567. Assert( pidoIn != NULL );
  568. HRESULT hr;
  569. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL, NULL };
  570. FORMATETC formatetc = { (CLIPFORMAT) m_cfDsObjectPicker, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
  571. PDS_SELECTION_LIST pds = NULL;
  572. DWORD sc;
  573. hr = THR( pidoIn->GetData( &formatetc, &stgmedium ) );
  574. if ( FAILED( hr ) )
  575. {
  576. goto CleanUp;
  577. } // if:
  578. pds = (PDS_SELECTION_LIST) GlobalLock( stgmedium.hGlobal );
  579. if ( pds == NULL )
  580. {
  581. sc = TW32( GetLastError() );
  582. hr = HRESULT_FROM_WIN32( sc );
  583. goto CleanUp;
  584. } // if:
  585. if ( pds->cItems == 1 )
  586. {
  587. SetDlgItemText( m_hwnd, IDC_SELNODE_E_COMPUTERNAME, pds->aDsSelection[ 0 ].pwzName );
  588. } // if:
  589. CleanUp:
  590. if ( pds != NULL )
  591. {
  592. GlobalUnlock( stgmedium.hGlobal );
  593. } // if:
  594. if ( stgmedium.hGlobal != NULL )
  595. {
  596. ReleaseStgMedium( &stgmedium );
  597. } // if:
  598. HRETURN( hr );
  599. } //*** CSelNodePage::HrGetSelection()
  600. //////////////////////////////////////////////////////////////////////////////
  601. //++
  602. //
  603. // static
  604. // CALLBACK
  605. // CSelNodePage::S_DlgProc
  606. //
  607. // Description:
  608. // Dialog proc for this page.
  609. //
  610. // Arguments:
  611. // hDlgIn
  612. // MsgIn
  613. // wParam
  614. // lParam
  615. //
  616. // Return Values:
  617. // FALSE
  618. // Other LRESULT values
  619. //
  620. // Remarks:
  621. //
  622. //--
  623. //////////////////////////////////////////////////////////////////////////////
  624. INT_PTR
  625. CALLBACK
  626. CSelNodePage::S_DlgProc(
  627. HWND hDlgIn,
  628. UINT MsgIn,
  629. WPARAM wParam,
  630. LPARAM lParam
  631. )
  632. {
  633. // Don't do TraceFunc because every mouse movement
  634. // will cause this function to be called.
  635. WndMsg( hDlgIn, MsgIn, wParam, lParam );
  636. LRESULT lr = FALSE;
  637. CSelNodePage * pPage = reinterpret_cast< CSelNodePage *> ( GetWindowLongPtr( hDlgIn, GWLP_USERDATA ) );
  638. if ( MsgIn == WM_INITDIALOG )
  639. {
  640. Assert( lParam != NULL );
  641. PROPSHEETPAGE * ppage = reinterpret_cast< PROPSHEETPAGE * >( lParam );
  642. SetWindowLongPtr( hDlgIn, GWLP_USERDATA, (LPARAM) ppage->lParam );
  643. pPage = reinterpret_cast< CSelNodePage * >( ppage->lParam );
  644. pPage->m_hwnd = hDlgIn;
  645. }
  646. if ( pPage != NULL )
  647. {
  648. Assert( hDlgIn == pPage->m_hwnd );
  649. switch( MsgIn )
  650. {
  651. case WM_INITDIALOG:
  652. lr = pPage->OnInitDialog( hDlgIn );
  653. break;
  654. case WM_NOTIFY:
  655. lr = pPage->OnNotify( wParam, reinterpret_cast< LPNMHDR >( lParam ) );
  656. break;
  657. case WM_COMMAND:
  658. lr= pPage->OnCommand( HIWORD( wParam ), LOWORD( wParam ), (HWND) lParam );
  659. break;
  660. // no default clause needed
  661. } // switch: message
  662. } // if: there is a page associated with the window
  663. return lr;
  664. } //*** CSelNodePage::S_DlgProc()