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.

1119 lines
27 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2001 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. DEFINE_THISCLASS("CSelNodesPage");
  17. //////////////////////////////////////////////////////////////////////////////
  18. //++
  19. //
  20. // CSelNodesPage::CSelNodesPage
  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. CSelNodesPage::CSelNodesPage(
  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_pcComputers = pcCountInout;
  55. m_prgbstrComputers = prgbstrComputersInout;
  56. m_pbstrClusterName = pbstrClusterNameIn;
  57. m_cfDsObjectPicker = 0;
  58. TraceFuncExit();
  59. } //*** CSelNodesPage::CSelNodesPage()
  60. //////////////////////////////////////////////////////////////////////////////
  61. //++
  62. //
  63. // CSelNodesPage::~CSelNodesPage
  64. //
  65. // Description:
  66. // Destructor.
  67. //
  68. // Arguments:
  69. // None.
  70. //
  71. // Return Values:
  72. // None.
  73. //
  74. // Remarks:
  75. //
  76. //--
  77. //////////////////////////////////////////////////////////////////////////////
  78. CSelNodesPage::~CSelNodesPage( void )
  79. {
  80. TraceFunc( "" );
  81. if ( m_psp != NULL )
  82. {
  83. m_psp->Release();
  84. }
  85. TraceFuncExit();
  86. } //*** CSelNodesPage::~CSelNodesPage()
  87. //////////////////////////////////////////////////////////////////////////////
  88. //++
  89. //
  90. // CSelNodesPage::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. CSelNodesPage::OnInitDialog(
  107. HWND hDlgIn
  108. )
  109. {
  110. TraceFunc( "" );
  111. HRESULT hr;
  112. BSTR bstrComputerName = NULL;
  113. LRESULT lr = FALSE; // Didn't set the focus.
  114. //
  115. // If a list of computers was already specified, validate them.
  116. //
  117. if ( ( *m_prgbstrComputers != NULL )
  118. && ( *m_pcComputers >= 1 )
  119. && ( (*m_prgbstrComputers)[ 0 ] != NULL )
  120. )
  121. {
  122. ULONG idxComputers;
  123. //
  124. // If a script pre-entered the machine names, make sure they end up in the UI.
  125. //
  126. for ( idxComputers = 0 ; idxComputers < *m_pcComputers ; idxComputers ++ )
  127. {
  128. hr = THR( HrValidateDnsHostname(
  129. hDlgIn
  130. , (*m_prgbstrComputers)[ idxComputers ]
  131. , mvdhoALLOW_FULL_NAME
  132. ) );
  133. if ( ! FAILED( hr ) )
  134. {
  135. //
  136. // Make sure the node is in the same domain as the cluster.
  137. //
  138. LPWSTR pszClusterDomain;
  139. LPWSTR pszComputerDomain;
  140. pszClusterDomain = wcschr( (*m_pbstrClusterName), L'.' );
  141. Assert( pszClusterDomain != NULL );
  142. pszComputerDomain = wcschr( (*m_prgbstrComputers)[ idxComputers ], L'.' );
  143. if ( pszComputerDomain != NULL )
  144. {
  145. if ( _wcsicmp( &pszClusterDomain[ 1 ], &pszComputerDomain[ 1 ] ) != 0 )
  146. {
  147. hr = THR( HRESULT_FROM_WIN32( ERROR_INVALID_COMPUTERNAME ) );
  148. THR( HrMessageBoxWithStatusString(
  149. m_hwnd
  150. , IDS_ERR_VALIDATING_NAME_TITLE
  151. , IDS_ERR_VALIDATING_NAME_TEXT
  152. , IDS_ERR_HOST_DOMAIN_DOESNT_MATCH_CLUSTER
  153. , 0
  154. , MB_OK | MB_ICONSTOP
  155. , NULL
  156. , *m_pbstrClusterName
  157. ) );
  158. } // if: computer not in same domain
  159. else
  160. {
  161. // Don't add the computer to the list with its domain name.
  162. *pszComputerDomain = L'\0';
  163. }
  164. } // if: computer domain specified
  165. } // if: DNS validation was successful
  166. if ( FAILED( hr ) )
  167. {
  168. //
  169. // Construct a comma-separated list of invalid computer names.
  170. // This list will be written to the edit control so the user
  171. // can correct mistakes.
  172. //
  173. if ( bstrComputerName == NULL )
  174. {
  175. //
  176. // First invalid computer name.
  177. //
  178. bstrComputerName = TraceSysAllocString( (*m_prgbstrComputers)[ idxComputers ] );
  179. if ( bstrComputerName == NULL )
  180. {
  181. THR( E_OUTOFMEMORY );
  182. }
  183. } // if: first invalid computer name
  184. else
  185. {
  186. BSTR bstr = NULL;
  187. //
  188. // Subsequent invalid computer name.
  189. //
  190. hr = THR( HrFormatStringIntoBSTR(
  191. L"%1!ws!,%2!ws!"
  192. , &bstr
  193. , bstrComputerName
  194. , (*m_prgbstrComputers)[ idxComputers ]
  195. ) );
  196. if ( FAILED( hr ) )
  197. {
  198. // Ignore error. What can we do?
  199. }
  200. else
  201. {
  202. TraceSysFreeString( bstrComputerName );
  203. bstrComputerName = bstr;
  204. }
  205. } // else: more than one invalid computer name
  206. } // if: error validating computer name
  207. else
  208. {
  209. ListBox_AddString( GetDlgItem( m_hwnd, IDC_SELNODE_LB_NODES ), (*m_prgbstrComputers)[ idxComputers ] );
  210. }
  211. } // for: each computer
  212. //
  213. // Set the edit control to the list of invalid computer names.
  214. //
  215. if ( bstrComputerName != NULL )
  216. {
  217. SetDlgItemText( m_hwnd, IDC_SELNODE_E_COMPUTERNAME, bstrComputerName );
  218. } // if: invalid computer names found
  219. } // if: computers were specified by the caller of the wizard
  220. else
  221. {
  222. DWORD dwStatus;
  223. DWORD dwClusterState;
  224. //
  225. // If the node is already in a cluster, don't have it default in the edit box.
  226. // If there is an error getting the "NodeClusterState", then default the node
  227. // name (it could be in the middle of cleaning up the node).
  228. //
  229. dwStatus = TW32( GetNodeClusterState( NULL, &dwClusterState ) );
  230. if ( ( dwStatus != ERROR_SUCCESS )
  231. || ( dwClusterState == ClusterStateNotConfigured ) )
  232. {
  233. hr = THR( HrGetComputerName( ComputerNameDnsHostname, &bstrComputerName ) );
  234. if ( FAILED( hr ) )
  235. {
  236. goto Cleanup;
  237. }
  238. }
  239. SetDlgItemText( m_hwnd, IDC_SELNODE_E_COMPUTERNAME, bstrComputerName );
  240. } // else: no list of computers was specified
  241. m_cfDsObjectPicker = RegisterClipboardFormat( CFSTR_DSOP_DS_SELECTION_LIST );
  242. if ( m_cfDsObjectPicker == 0 )
  243. {
  244. TW32( GetLastError() );
  245. //
  246. // If registering the clipboard format fails, then disable the Browse
  247. // button.
  248. //
  249. EnableWindow( GetDlgItem( hDlgIn, IDC_SELNODE_PB_BROWSE ), FALSE );
  250. } // if:
  251. Cleanup:
  252. TraceSysFreeString( bstrComputerName );
  253. RETURN( lr );
  254. } //*** CSelNodesPage::OnInitDialog()
  255. //////////////////////////////////////////////////////////////////////////////
  256. //++
  257. //
  258. // CSelNodesPage::OnCommand
  259. //
  260. // Description:
  261. //
  262. // Arguments:
  263. // idNotificationIn
  264. // idControlIn
  265. // hwndSenderIn
  266. //
  267. // Return Values:
  268. // TRUE
  269. // FALSE
  270. //
  271. // Remarks:
  272. //
  273. //--
  274. //////////////////////////////////////////////////////////////////////////////
  275. LRESULT
  276. CSelNodesPage::OnCommand(
  277. UINT idNotificationIn,
  278. UINT idControlIn,
  279. HWND hwndSenderIn
  280. )
  281. {
  282. TraceFunc( "" );
  283. LRESULT lr = FALSE;
  284. switch ( idControlIn )
  285. {
  286. case IDC_SELNODE_E_COMPUTERNAME:
  287. if ( idNotificationIn == EN_CHANGE )
  288. {
  289. THR( HrUpdateWizardButtons() );
  290. lr = TRUE;
  291. }
  292. break;
  293. case IDC_SELNODE_LB_NODES:
  294. if ( idNotificationIn == LBN_SELCHANGE )
  295. {
  296. THR( HrUpdateWizardButtons() );
  297. lr = TRUE;
  298. }
  299. break;
  300. case IDC_SELNODE_PB_BROWSE:
  301. if ( idNotificationIn == BN_CLICKED )
  302. {
  303. THR( HrBrowse() );
  304. lr = TRUE;
  305. }
  306. break;
  307. case IDC_SELNODE_PB_ADD:
  308. if ( idNotificationIn == BN_CLICKED )
  309. {
  310. THR( HrAddNodeToList() );
  311. lr = TRUE;
  312. }
  313. break;
  314. case IDC_SELNODE_PB_REMOVE:
  315. if ( idNotificationIn == BN_CLICKED )
  316. {
  317. THR( HrRemoveNodeFromList() );
  318. lr = TRUE;
  319. }
  320. break;
  321. } // switch: idControlIn
  322. RETURN( lr );
  323. } //*** CSelNodesPage::OnCommand()
  324. //////////////////////////////////////////////////////////////////////////////
  325. //++
  326. //
  327. // CSelNodesPage::HrUpdateWizardButtons
  328. //
  329. // Description:
  330. //
  331. // Arguments:
  332. // fSetActiveIn - TRUE = called while handling PSN_SETACTIVE.
  333. //
  334. // Return Values:
  335. // S_OK
  336. //
  337. // Remarks:
  338. //
  339. //--
  340. //////////////////////////////////////////////////////////////////////////////
  341. HRESULT
  342. CSelNodesPage::HrUpdateWizardButtons(
  343. bool fSetActiveIn // = false
  344. )
  345. {
  346. TraceFunc( "" );
  347. HRESULT hr = S_OK;
  348. HWND hwndList = GetDlgItem( m_hwnd, IDC_SELNODE_LB_NODES );
  349. DWORD dwFlags = PSWIZB_BACK | PSWIZB_NEXT;
  350. DWORD dwLen;
  351. LRESULT lr;
  352. // Disable the Next button if there are no entries in the list box
  353. // or if the edit control is not empty.
  354. lr = ListBox_GetCount( hwndList );
  355. dwLen = GetWindowTextLength( GetDlgItem( m_hwnd, IDC_SELNODE_E_COMPUTERNAME ) );
  356. if ( ( lr == 0 )
  357. || ( dwLen != 0 ) )
  358. {
  359. dwFlags &= ~PSWIZB_NEXT;
  360. }
  361. // This cannot be done synchronously if called while handling
  362. // PSN_SETACTIVE. Otherwise, do it synchronously.
  363. if ( fSetActiveIn )
  364. {
  365. PropSheet_SetWizButtons( GetParent( m_hwnd ), dwFlags );
  366. }
  367. else
  368. {
  369. SendMessage( GetParent( m_hwnd ), PSM_SETWIZBUTTONS, 0, (LPARAM) dwFlags );
  370. }
  371. // Enable or disable the Add button based on whether there is text
  372. // in the edit control or not.
  373. if ( dwLen == 0 )
  374. {
  375. EnableWindow( GetDlgItem( m_hwnd, IDC_SELNODE_PB_ADD ), FALSE );
  376. }
  377. else
  378. {
  379. EnableWindow( GetDlgItem( m_hwnd, IDC_SELNODE_PB_ADD ), TRUE );
  380. SendMessage( m_hwnd, DM_SETDEFID, IDC_SELNODE_PB_ADD, 0 );
  381. }
  382. // Enable or disable the Remove button based whether an item is
  383. // selected in the list box or not.
  384. lr = ListBox_GetCurSel( hwndList );
  385. if ( lr == LB_ERR )
  386. {
  387. EnableWindow( GetDlgItem( m_hwnd, IDC_SELNODE_PB_REMOVE ), FALSE );
  388. }
  389. else
  390. {
  391. EnableWindow( GetDlgItem( m_hwnd, IDC_SELNODE_PB_REMOVE ), TRUE );
  392. }
  393. HRETURN( hr );
  394. } //*** CSelNodesPage::HrUpdateWizardButtons()
  395. //////////////////////////////////////////////////////////////////////////////
  396. //++
  397. //
  398. // CSelNodesPage::HrAddNodeToList
  399. //
  400. // Description:
  401. //
  402. // Arguments:
  403. // None.
  404. //
  405. // Return Values:
  406. // S_OK
  407. // E_OUTOFMEMORY
  408. //
  409. // Remarks:
  410. //
  411. //--
  412. //////////////////////////////////////////////////////////////////////////////
  413. HRESULT
  414. CSelNodesPage::HrAddNodeToList( void )
  415. {
  416. TraceFunc( "" );
  417. HRESULT hr;
  418. DNS_STATUS dnsStatus;
  419. DWORD dwLen;
  420. int idcFocus = 0;
  421. LPWSTR psz;
  422. LPWSTR pszComputerName;
  423. LPWSTR pszFreeBuffer = NULL;
  424. HWND hwndList = GetDlgItem( m_hwnd, IDC_SELNODE_LB_NODES );
  425. HWND hwndEdit = GetDlgItem( m_hwnd, IDC_SELNODE_E_COMPUTERNAME );
  426. dwLen = GetWindowTextLength( hwndEdit );
  427. if ( dwLen == 0 )
  428. {
  429. hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
  430. if ( hr == HRESULT_FROM_WIN32( ERROR_SUCCESS ) )
  431. {
  432. AssertMsg( dwLen != 0, "How did we get here?!" );
  433. }
  434. goto Error;
  435. }
  436. pszComputerName = (LPWSTR) TraceAlloc( 0, ( dwLen + 1 ) * sizeof(WCHAR) );
  437. if ( pszComputerName == NULL )
  438. {
  439. goto OutOfMemory;
  440. }
  441. pszFreeBuffer = pszComputerName;
  442. dwLen = GetDlgItemText( m_hwnd, IDC_SELNODE_E_COMPUTERNAME, pszComputerName, dwLen + 1 );
  443. AssertMsg( dwLen != 0, "How did we get here?!" );
  444. for ( ; pszComputerName != NULL ; pszComputerName = psz )
  445. {
  446. // Allow comma, semi-colon, and space delimiters.
  447. psz = wcspbrk( pszComputerName, L",; " );
  448. if ( psz != NULL )
  449. {
  450. *psz = L'\0';
  451. psz++;
  452. }
  453. hr = THR( HrValidateDnsHostname(
  454. m_hwnd
  455. , pszComputerName
  456. , mvdhoALLOW_ONLY_HOSTNAME_LABEL
  457. ) );
  458. if ( FAILED( hr ) )
  459. {
  460. idcFocus = IDC_SELNODE_E_COMPUTERNAME;
  461. goto Error;
  462. }
  463. ListBox_AddString( GetDlgItem( m_hwnd, IDC_SELNODE_LB_NODES ), pszComputerName );
  464. } // for: pszComputerName;
  465. SetDlgItemText( m_hwnd, IDC_SELNODE_E_COMPUTERNAME, L"" );
  466. hr = THR( HrUpdateWizardButtons() );
  467. Error:
  468. TraceFree( pszFreeBuffer );
  469. if ( idcFocus != 0 )
  470. {
  471. SetFocus( GetDlgItem( m_hwnd, idcFocus ) );
  472. }
  473. HRETURN( hr );
  474. OutOfMemory:
  475. hr = E_OUTOFMEMORY;
  476. goto Error;
  477. } //*** CSelNodesPage::HrAddNodeToList()
  478. //////////////////////////////////////////////////////////////////////////////
  479. //++
  480. //
  481. // CSelNodesPage::HrRemoveNodeFromList
  482. //
  483. // Description:
  484. //
  485. // Arguments:
  486. // None.
  487. //
  488. // Return Values:
  489. // S_OK
  490. //
  491. // Remarks:
  492. //
  493. //--
  494. //////////////////////////////////////////////////////////////////////////////
  495. HRESULT
  496. CSelNodesPage::HrRemoveNodeFromList( void )
  497. {
  498. TraceFunc( "" );
  499. HRESULT hr;
  500. LRESULT lr;
  501. HWND hwndList = GetDlgItem( m_hwnd, IDC_SELNODE_LB_NODES );
  502. lr = ListBox_GetCurSel( hwndList );
  503. if ( lr != LB_ERR )
  504. {
  505. ListBox_DeleteString( hwndList, lr );
  506. }
  507. hr = THR( HrUpdateWizardButtons() );
  508. HRETURN( hr );
  509. } //*** CSelNodesPage::HrRemoveNodeFromList()
  510. //////////////////////////////////////////////////////////////////////////////
  511. //++
  512. //
  513. // CSelNodesPage::OnNotifySetActive
  514. //
  515. // Description:
  516. //
  517. // Arguments:
  518. // None.
  519. //
  520. // Return Values:
  521. // TRUE
  522. //
  523. // Remarks:
  524. //
  525. //--
  526. //////////////////////////////////////////////////////////////////////////////
  527. LRESULT
  528. CSelNodesPage::OnNotifySetActive( void )
  529. {
  530. TraceFunc( "" );
  531. LRESULT lr = TRUE;
  532. THR( HrUpdateWizardButtons( true /* fSetActiveIn */ ) );
  533. RETURN( lr );
  534. } //*** CSelNodesPage::OnNotifySetActive()
  535. //////////////////////////////////////////////////////////////////////////////
  536. //++
  537. //
  538. // CSelNodesPage::OnNotifyQueryCancel
  539. //
  540. // Description:
  541. //
  542. // Arguments:
  543. // None.
  544. //
  545. // Return Values:
  546. // TRUE
  547. //
  548. // Remarks:
  549. //
  550. //--
  551. //////////////////////////////////////////////////////////////////////////////
  552. LRESULT
  553. CSelNodesPage::OnNotifyQueryCancel( void )
  554. {
  555. TraceFunc( "" );
  556. LRESULT lr = TRUE;
  557. int iRet;
  558. iRet = MessageBoxFromStrings( m_hwnd,
  559. IDS_QUERY_CANCEL_TITLE,
  560. IDS_QUERY_CANCEL_TEXT,
  561. MB_YESNO
  562. );
  563. if ( iRet == IDNO )
  564. {
  565. SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 );
  566. }
  567. RETURN( lr );
  568. } //*** CSelNodesPage::OnNotifyQueryCancel()
  569. //////////////////////////////////////////////////////////////////////////////
  570. //++
  571. //
  572. // CSelNodesPage::OnNotifyWizNext
  573. //
  574. // Description:
  575. //
  576. // Arguments:
  577. // None.
  578. //
  579. // Return Values:
  580. // TRUE
  581. // LB_ERR
  582. // Other LRESULT values.
  583. //
  584. // Remarks:
  585. //
  586. //--
  587. //////////////////////////////////////////////////////////////////////////////
  588. LRESULT
  589. CSelNodesPage::OnNotifyWizNext( void )
  590. {
  591. TraceFunc( "" );
  592. LPWSTR pszDomain;
  593. DWORD dwLen;
  594. WCHAR szComputerName[ DNS_MAX_NAME_BUFFER_LENGTH ];
  595. LRESULT lr = TRUE;
  596. HWND hwndList = GetDlgItem( m_hwnd, IDC_SELNODE_LB_NODES );
  597. //
  598. // Free old list (if any)
  599. //
  600. while ( *m_pcComputers != 0 )
  601. {
  602. (*m_pcComputers) --;
  603. TraceSysFreeString( (*m_prgbstrComputers)[ *m_pcComputers ] );
  604. }
  605. //
  606. // Find out how many are in the new list.
  607. //
  608. lr = ListBox_GetCount( hwndList );
  609. if ( lr == LB_ERR )
  610. {
  611. goto Error;
  612. }
  613. // Check to see if we have a FQDN cluster name
  614. pszDomain = wcschr( *m_pbstrClusterName, L'.' );
  615. //
  616. // Loop thru adding the FQDN node names to the list of nodes.
  617. //
  618. Assert( lr >= 0 );
  619. TraceFree( *m_prgbstrComputers );
  620. //
  621. // Need to make a new list.
  622. //
  623. *m_prgbstrComputers = (BSTR *) TraceAlloc( HEAP_ZERO_MEMORY, (size_t) lr * sizeof(BSTR) );
  624. if ( *m_prgbstrComputers == NULL )
  625. {
  626. goto OutOfMemory;
  627. }
  628. for ( *m_pcComputers = 0; *m_pcComputers < (ULONG) lr; (*m_pcComputers) ++ )
  629. {
  630. dwLen = ListBox_GetText( hwndList, *m_pcComputers, szComputerName );
  631. Assert( dwLen < ARRAYSIZE( szComputerName ) );
  632. // Append domain name to node if present.
  633. if ( pszDomain != NULL )
  634. {
  635. wcsncpy( &szComputerName[ dwLen ], pszDomain, ARRAYSIZE( szComputerName ) - dwLen - 1 /* NULL */ );
  636. }
  637. // Add a new entry
  638. (*m_prgbstrComputers)[ *m_pcComputers ] = TraceSysAllocString( szComputerName );
  639. if ( (*m_prgbstrComputers)[ *m_pcComputers ] == NULL )
  640. {
  641. goto OutOfMemory;
  642. }
  643. } // for: *m_pcComputers
  644. Cleanup:
  645. RETURN( lr );
  646. OutOfMemory:
  647. LogMsg( "Out of memory." );
  648. // fall thru
  649. Error:
  650. SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, -1 );
  651. goto Cleanup;
  652. } //*** CSelNodesPage::OnNotifyWizNext()
  653. //////////////////////////////////////////////////////////////////////////////
  654. //++
  655. //
  656. // CSelNodesPage::OnNotify
  657. //
  658. // Description:
  659. //
  660. // Arguments:
  661. // idCtrlIn
  662. // pnmhdrIn
  663. //
  664. // Return Values:
  665. // TRUE
  666. // Other LRESULT values.
  667. //
  668. // Remarks:
  669. //
  670. //--
  671. //////////////////////////////////////////////////////////////////////////////
  672. LRESULT
  673. CSelNodesPage::OnNotify(
  674. WPARAM idCtrlIn,
  675. LPNMHDR pnmhdrIn
  676. )
  677. {
  678. TraceFunc( "" );
  679. LRESULT lr = TRUE;
  680. SetWindowLongPtr( m_hwnd, DWLP_MSGRESULT, 0 );
  681. switch( pnmhdrIn->code )
  682. {
  683. case PSN_SETACTIVE:
  684. lr = OnNotifySetActive();
  685. break;
  686. case PSN_WIZNEXT:
  687. lr = OnNotifyWizNext();
  688. break;
  689. case PSN_QUERYCANCEL:
  690. lr = OnNotifyQueryCancel();
  691. break;
  692. } // switch: notification code
  693. RETURN( lr );
  694. } //*** CSelNodesPage::OnNotify()
  695. //////////////////////////////////////////////////////////////////////////////
  696. //++
  697. //
  698. // CSelNodePage::HrBrowse
  699. //
  700. // Description:
  701. //
  702. // Arguments:
  703. // None.
  704. //
  705. // Return Values:
  706. // S_OK
  707. // Other HRESULT values.
  708. //
  709. // Remarks:
  710. //
  711. //--
  712. //////////////////////////////////////////////////////////////////////////////
  713. HRESULT
  714. CSelNodesPage::HrBrowse( void )
  715. {
  716. TraceFunc( "" );
  717. HRESULT hr = S_OK;
  718. IDsObjectPicker * piop = NULL;
  719. IDataObject * pido = NULL;
  720. HCURSOR hOldCursor = NULL;
  721. hOldCursor = SetCursor( LoadCursor( g_hInstance, IDC_WAIT ) );
  722. // Create an instance of the object picker.
  723. hr = THR( CoCreateInstance( CLSID_DsObjectPicker, NULL, CLSCTX_INPROC_SERVER, IID_IDsObjectPicker, (void **) &piop ) );
  724. if ( FAILED( hr ) )
  725. {
  726. goto Cleanup;
  727. } // if:
  728. // Initialize the object picker instance.
  729. hr = THR( HrInitObjectPicker( piop ) );
  730. if ( FAILED( hr ) )
  731. {
  732. goto Cleanup;
  733. } // if:
  734. SetCursor( hOldCursor );
  735. // Invoke the modal dialog.
  736. hr = THR( piop->InvokeDialog( m_hwnd, &pido ) );
  737. if ( FAILED( hr ) )
  738. {
  739. goto Cleanup;
  740. } // if:
  741. if ( hr == S_OK )
  742. {
  743. hr = THR( HrGetSelections( pido ) );
  744. } // if:
  745. else if ( hr == S_FALSE )
  746. {
  747. hr = S_OK; // don't want to squawk in the caller...
  748. } // else if:
  749. Cleanup:
  750. if ( pido != NULL )
  751. {
  752. pido->Release();
  753. } // if:
  754. if ( piop != NULL )
  755. {
  756. piop->Release();
  757. } // if:
  758. HRETURN( hr );
  759. } //*** CSelNodesPage::HrBrowse()
  760. //////////////////////////////////////////////////////////////////////////////
  761. //++
  762. //
  763. // CSelNodesPage::HrInitObjectPicker
  764. //
  765. // Description:
  766. // Initialize the Object Picker dialog.
  767. //
  768. // Arguments:
  769. // piopIn -- IDsObjectPicker
  770. //
  771. // Return Values:
  772. // HRESULT values.
  773. //
  774. // Remarks:
  775. //
  776. //--
  777. //////////////////////////////////////////////////////////////////////////////
  778. HRESULT
  779. CSelNodesPage::HrInitObjectPicker( IDsObjectPicker * piopIn )
  780. {
  781. TraceFunc( "" );
  782. DSOP_SCOPE_INIT_INFO rgScopeInit[ 1 ];
  783. DSOP_INIT_INFO iiInfo;
  784. ZeroMemory( rgScopeInit, sizeof( DSOP_SCOPE_INIT_INFO ) * (sizeof( rgScopeInit ) / sizeof( rgScopeInit[ 0 ] ) ) );
  785. rgScopeInit[0].cbSize = sizeof( DSOP_SCOPE_INIT_INFO );
  786. rgScopeInit[0].flType = DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN;
  787. rgScopeInit[0].flScope = DSOP_SCOPE_FLAG_STARTING_SCOPE;
  788. rgScopeInit[0].FilterFlags.Uplevel.flBothModes = DSOP_FILTER_COMPUTERS;
  789. rgScopeInit[0].FilterFlags.flDownlevel = DSOP_DOWNLEVEL_FILTER_COMPUTERS;
  790. ZeroMemory( &iiInfo, sizeof( iiInfo ) );
  791. iiInfo.cbSize = sizeof( iiInfo );
  792. iiInfo.pwzTargetComputer = NULL;
  793. iiInfo.cDsScopeInfos = 1;
  794. iiInfo.aDsScopeInfos = rgScopeInit;
  795. iiInfo.flOptions = DSOP_FLAG_MULTISELECT;
  796. HRETURN( piopIn->Initialize( &iiInfo) );
  797. } //*** CSelNodesPage::HrInitObjectPicker
  798. //////////////////////////////////////////////////////////////////////////////
  799. //++
  800. //
  801. // CSelNodePage::HrGetSelections
  802. //
  803. // Description:
  804. // Get selections from the Object Picker dialog.
  805. //
  806. // Arguments:
  807. // pidoIn -- IDataObject
  808. //
  809. // Return Values:
  810. // S_OK
  811. // E_OUTOFMEMORY
  812. // Other HRESULT values.
  813. //
  814. // Remarks:
  815. //
  816. //--
  817. //////////////////////////////////////////////////////////////////////////////
  818. HRESULT
  819. CSelNodesPage::HrGetSelections(
  820. IDataObject * pidoIn
  821. )
  822. {
  823. TraceFunc( "" );
  824. Assert( pidoIn != NULL );
  825. HRESULT hr;
  826. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL, NULL };
  827. FORMATETC formatetc = { (CLIPFORMAT) m_cfDsObjectPicker, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
  828. PDS_SELECTION_LIST pds = NULL;
  829. DWORD sc;
  830. ULONG idx;
  831. HWND hwndEdit = GetDlgItem( m_hwnd, IDC_SELNODE_E_COMPUTERNAME );
  832. WCHAR * psz = NULL;
  833. ULONG cch = 0;
  834. hr = THR( pidoIn->GetData( &formatetc, &stgmedium ) );
  835. if ( FAILED( hr ) )
  836. {
  837. goto Cleanup;
  838. }
  839. pds = (PDS_SELECTION_LIST) GlobalLock( stgmedium.hGlobal );
  840. if ( pds == NULL )
  841. {
  842. sc = TW32( GetLastError() );
  843. hr = HRESULT_FROM_WIN32( sc );
  844. goto Cleanup;
  845. } // if:
  846. for ( idx = 0 ; idx < pds->cItems; idx++ )
  847. {
  848. cch += wcslen( pds->aDsSelection[ idx ].pwzName ) + 2; // EOS plus the ';'
  849. psz = (WCHAR *) TraceReAlloc( psz, cch * sizeof( WCHAR ), HEAP_ZERO_MEMORY );
  850. if ( psz == NULL )
  851. {
  852. goto OutOfMemory;
  853. } // if:
  854. wcscat( psz, pds->aDsSelection[ idx ].pwzName );
  855. wcscat( psz, L"," );
  856. } // for:
  857. //
  858. // Remove the last trailing comma ','
  859. //
  860. cch = wcslen( psz );
  861. psz[ cch - 1 ] = L'\0';
  862. Edit_SetText( hwndEdit, psz );
  863. goto Cleanup;
  864. OutOfMemory:
  865. hr = THR( E_OUTOFMEMORY );
  866. Cleanup:
  867. if ( pds != NULL )
  868. {
  869. GlobalUnlock( stgmedium.hGlobal );
  870. } // if:
  871. if ( stgmedium.hGlobal != NULL )
  872. {
  873. ReleaseStgMedium( &stgmedium );
  874. } // if:
  875. TraceFree( psz );
  876. HRETURN( hr );
  877. } //*** CSelNodesPage::HrGetSelections()
  878. //////////////////////////////////////////////////////////////////////////////
  879. //++
  880. //
  881. // static
  882. // CALLBACK
  883. // CSelNodesPage::S_DlgProc
  884. //
  885. // Description:
  886. // Dialog proc for this page.
  887. //
  888. // Arguments:
  889. // hDlgIn
  890. // MsgIn
  891. // wParam
  892. // lParam
  893. //
  894. // Return Values:
  895. // FALSE
  896. // Other LRESULT values.
  897. //
  898. // Remarks:
  899. //
  900. //--
  901. //////////////////////////////////////////////////////////////////////////////
  902. INT_PTR
  903. CALLBACK
  904. CSelNodesPage::S_DlgProc(
  905. HWND hDlgIn,
  906. UINT MsgIn,
  907. WPARAM wParam,
  908. LPARAM lParam
  909. )
  910. {
  911. // Don't do TraceFunc because every mouse movement
  912. // will cause this function to be called.
  913. WndMsg( hDlgIn, MsgIn, wParam, lParam );
  914. LRESULT lr = FALSE;
  915. CSelNodesPage * pPage = reinterpret_cast< CSelNodesPage *> ( GetWindowLongPtr( hDlgIn, GWLP_USERDATA ) );
  916. if ( MsgIn == WM_INITDIALOG )
  917. {
  918. Assert( lParam != NULL );
  919. PROPSHEETPAGE * ppage = reinterpret_cast< PROPSHEETPAGE * >( lParam );
  920. SetWindowLongPtr( hDlgIn, GWLP_USERDATA, (LPARAM) ppage->lParam );
  921. pPage = reinterpret_cast< CSelNodesPage * >( ppage->lParam );
  922. pPage->m_hwnd = hDlgIn;
  923. }
  924. if ( pPage != NULL )
  925. {
  926. Assert( hDlgIn == pPage->m_hwnd );
  927. switch( MsgIn )
  928. {
  929. case WM_INITDIALOG:
  930. lr = pPage->OnInitDialog( hDlgIn );
  931. break;
  932. case WM_NOTIFY:
  933. lr = pPage->OnNotify( wParam, reinterpret_cast< LPNMHDR >( lParam ) );
  934. break;
  935. case WM_COMMAND:
  936. lr= pPage->OnCommand( HIWORD( wParam ), LOWORD( wParam ), (HWND) lParam );
  937. break;
  938. // no default clause needed
  939. } // switch: message
  940. } // if: there is a page associated with the window
  941. return lr;
  942. } //*** CSelNodesPage::S_DlgProc()