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.

1052 lines
27 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // QuorumDlg.cpp
  7. //
  8. // Maintained By:
  9. // David Potter (DavidP) 03-APR-2001
  10. //
  11. //////////////////////////////////////////////////////////////////////////////
  12. #include "Pch.h"
  13. #include "QuorumDlg.h"
  14. #include "WizardUtils.h"
  15. #include "WizardHelp.h"
  16. #include "SummaryPage.h"
  17. #include <HtmlHelp.h>
  18. //////////////////////////////////////////////////////////////////////////////
  19. // Context-sensitive help table.
  20. //////////////////////////////////////////////////////////////////////////////
  21. const DWORD g_rgidQuorumDlgHelpIDs[] =
  22. {
  23. IDC_QUORUM_S_QUORUM, IDH_QUORUM_S_QUORUM,
  24. IDC_QUORUM_CB_QUORUM, IDH_QUORUM_S_QUORUM,
  25. 0, 0
  26. };
  27. //////////////////////////////////////////////////////////////////////////////
  28. // Static Function Prototypes
  29. //////////////////////////////////////////////////////////////////////////////
  30. //////////////////////////////////////////////////////////////////////////////
  31. //++
  32. //
  33. // CQuorumDlg::S_HrDisplayModalDialog
  34. //
  35. // Description:
  36. // Display the dialog box.
  37. //
  38. // Arguments:
  39. // hwndParentIn - Parent window for the dialog box.
  40. // pccwIn - CClusCfgWizard pointer for talking to the middle tier.
  41. // pssaOut - array of all the initial IsManaged states
  42. //
  43. // Return Values:
  44. // S_OK - Operation completed successfully.
  45. //
  46. // Remarks:
  47. //
  48. //--
  49. //////////////////////////////////////////////////////////////////////////////
  50. HRESULT
  51. CQuorumDlg::S_HrDisplayModalDialog(
  52. HWND hwndParentIn
  53. , CClusCfgWizard * pccwIn
  54. , SStateArray * pssaOut
  55. )
  56. {
  57. TraceFunc( "" );
  58. Assert( pccwIn != NULL );
  59. Assert( pssaOut != NULL );
  60. HRESULT hr = S_OK;
  61. INT_PTR dlgResult = IDOK;
  62. // Display the dialog.
  63. {
  64. CQuorumDlg dlg( pccwIn, pssaOut );
  65. dlgResult = DialogBoxParam(
  66. g_hInstance
  67. , MAKEINTRESOURCE( IDD_QUORUM )
  68. , hwndParentIn
  69. , CQuorumDlg::S_DlgProc
  70. , (LPARAM) &dlg
  71. );
  72. if ( dlgResult == IDOK )
  73. hr = S_OK;
  74. else
  75. hr = S_FALSE;
  76. }
  77. HRETURN( hr );
  78. } //*** CQuorumDlg::S_HrDisplayModalDialog
  79. //////////////////////////////////////////////////////////////////////////////
  80. //++
  81. //
  82. // FIsValidResource
  83. //
  84. // Description:
  85. // Determines whether the resource is a valid selection as a quorum
  86. // resource.
  87. //
  88. // Arguments:
  89. // pResourceIn - the resource in question.
  90. //
  91. // Return Values:
  92. // true - the resource is valid.
  93. // false - the resource is not valid.
  94. //
  95. // Remarks:
  96. // A resource is valid if it is quorum capable and it is not an "unknown"
  97. // quorum.
  98. //
  99. //--
  100. //////////////////////////////////////////////////////////////////////////////
  101. static
  102. bool
  103. FIsValidResource(
  104. IClusCfgManagedResourceInfo * pResourceIn
  105. )
  106. {
  107. TraceFunc( "" );
  108. HRESULT hr = S_OK;
  109. bool fValid = false;
  110. BSTR bstrDeviceID = NULL;
  111. hr = STHR( pResourceIn->IsQuorumCapable() );
  112. if ( FAILED( hr ) )
  113. {
  114. goto Cleanup;
  115. } // if:
  116. //
  117. // The resource is not quorum capable so there is no reason
  118. // to continue.
  119. //
  120. if ( hr == S_FALSE )
  121. {
  122. goto Cleanup;
  123. } // if:
  124. hr = THR( pResourceIn->GetUID( &bstrDeviceID ) );
  125. if ( FAILED( hr ) )
  126. {
  127. LogMsg( L"[WIZ] FIsValidResource() cannot get the UID for the passed in managed resource. (hr = %#08x)" );
  128. goto Cleanup;
  129. } // if:
  130. TraceMemoryAddBSTR( bstrDeviceID );
  131. //
  132. // If this is the "Unknown Quorum" resource then we don't want to show it
  133. // in the drop down list.
  134. //
  135. if ( NStringCchCompareCase( g_szUnknownQuorumUID, RTL_NUMBER_OF( g_szUnknownQuorumUID ), bstrDeviceID, SysStringLen( bstrDeviceID ) + 1 ) == 0 )
  136. {
  137. goto Cleanup;
  138. } // if:
  139. fValid = true;
  140. Cleanup:
  141. TraceSysFreeString( bstrDeviceID );
  142. RETURN( fValid );
  143. } //*** FIsValidResource
  144. //////////////////////////////////////////////////////////////////////////////
  145. //++
  146. //
  147. // CQuorumDlg::CQuorumDlg
  148. //
  149. // Description:
  150. // Constructor.
  151. //
  152. // Arguments:
  153. // pccwIn - CClusCfgWizard for talking to the middle tier.
  154. // pssaOut - array of all the initial IsManaged states.
  155. //
  156. // Return Values:
  157. // None.
  158. //
  159. //--
  160. //////////////////////////////////////////////////////////////////////////////
  161. CQuorumDlg::CQuorumDlg(
  162. CClusCfgWizard * pccwIn
  163. , SStateArray * pssaOut
  164. )
  165. : m_pccw( pccwIn )
  166. , m_pssa( pssaOut )
  167. , m_rgpResources( NULL )
  168. , m_cValidResources( 0 )
  169. , m_idxQuorumResource( 0 )
  170. , m_hComboBox( NULL )
  171. , m_fQuorumAlreadySet( false )
  172. {
  173. TraceFunc( "" );
  174. Assert( pccwIn != NULL );
  175. Assert( pssaOut != NULL );
  176. // m_hwnd
  177. m_pccw->AddRef();
  178. TraceFuncExit();
  179. } //*** CQuorumDlg::CQuorumDlg
  180. //////////////////////////////////////////////////////////////////////////////
  181. //++
  182. //
  183. // CQuorumDlg::~CQuorumDlg
  184. //
  185. // Description:
  186. // Destructor.
  187. //
  188. // Arguments:
  189. // None.
  190. //
  191. // Return Values:
  192. // None.
  193. //
  194. //--
  195. //////////////////////////////////////////////////////////////////////////////
  196. CQuorumDlg::~CQuorumDlg( void )
  197. {
  198. TraceFunc( "" );
  199. DWORD idxResource = 0;
  200. for ( idxResource = 0; idxResource < m_cValidResources; idxResource += 1 )
  201. m_rgpResources[ idxResource ]->Release();
  202. delete [] m_rgpResources;
  203. if ( m_pccw != NULL )
  204. {
  205. m_pccw->Release();
  206. }
  207. TraceFuncExit();
  208. } //*** CQuorumDlg::~CQuorumDlg
  209. //////////////////////////////////////////////////////////////////////////////
  210. //++
  211. //
  212. // CQuorumDlg::S_DlgProc
  213. //
  214. // Description:
  215. // Dialog proc for the Quorum dialog box.
  216. //
  217. // Arguments:
  218. // hwndDlgIn - Dialog box window handle.
  219. // nMsgIn - Message ID.
  220. // wParam - Message-specific parameter.
  221. // lParam - Message-specific parameter.
  222. //
  223. // Return Values:
  224. // TRUE - Message has been handled.
  225. // FALSE - Message has not been handled yet.
  226. //
  227. // Remarks:
  228. // It is expected that this dialog box is invoked by a call to
  229. // DialogBoxParam() with the lParam argument set to the address of the
  230. // instance of this class.
  231. //
  232. //--
  233. //////////////////////////////////////////////////////////////////////////////
  234. INT_PTR
  235. CALLBACK
  236. CQuorumDlg::S_DlgProc(
  237. HWND hwndDlgIn
  238. , UINT nMsgIn
  239. , WPARAM wParam
  240. , LPARAM lParam
  241. )
  242. {
  243. // Don't do TraceFunc because every mouse movement
  244. // will cause this function to be called.
  245. WndMsg( hwndDlgIn, nMsgIn, wParam, lParam );
  246. LRESULT lr = FALSE;
  247. CQuorumDlg * pdlg;
  248. //
  249. // Get a pointer to the class.
  250. //
  251. if ( nMsgIn == WM_INITDIALOG )
  252. {
  253. SetWindowLongPtr( hwndDlgIn, GWLP_USERDATA, lParam );
  254. pdlg = reinterpret_cast< CQuorumDlg * >( lParam );
  255. pdlg->m_hwnd = hwndDlgIn;
  256. }
  257. else
  258. {
  259. pdlg = reinterpret_cast< CQuorumDlg * >( GetWindowLongPtr( hwndDlgIn, GWLP_USERDATA ) );
  260. }
  261. if ( pdlg != NULL )
  262. {
  263. Assert( hwndDlgIn == pdlg->m_hwnd );
  264. switch( nMsgIn )
  265. {
  266. case WM_INITDIALOG:
  267. lr = pdlg->OnInitDialog();
  268. break;
  269. case WM_COMMAND:
  270. lr = pdlg->OnCommand( HIWORD( wParam ), LOWORD( wParam ), reinterpret_cast< HWND >( lParam ) );
  271. break;
  272. case WM_HELP:
  273. WinHelp(
  274. (HWND)((LPHELPINFO) lParam)->hItemHandle,
  275. CLUSCFG_HELP_FILE,
  276. HELP_WM_HELP,
  277. (ULONG_PTR) g_rgidQuorumDlgHelpIDs
  278. );
  279. break;
  280. case WM_CONTEXTMENU:
  281. WinHelp(
  282. (HWND)wParam,
  283. CLUSCFG_HELP_FILE,
  284. HELP_CONTEXTMENU,
  285. (ULONG_PTR) g_rgidQuorumDlgHelpIDs
  286. );
  287. break;
  288. // no default clause needed
  289. } // switch: nMsgIn
  290. } // if: page is specified
  291. return lr;
  292. } //*** CQuorumDlg::S_DlgProc
  293. //////////////////////////////////////////////////////////////////////////////
  294. //++
  295. //
  296. // CQuorumDlg::OnInitDialog
  297. //
  298. // Description:
  299. // Handler for the WM_INITDIALOG message.
  300. //
  301. // Arguments:
  302. // None.
  303. //
  304. // Return Values:
  305. // TRUE Focus has been set.
  306. // FALSE Focus has not been set.
  307. //--
  308. //////////////////////////////////////////////////////////////////////////////
  309. LRESULT
  310. CQuorumDlg::OnInitDialog( void )
  311. {
  312. TraceFunc( "" );
  313. LRESULT lr = TRUE; // did set focus
  314. HRESULT hr = S_OK;
  315. DWORD sc;
  316. DWORD idxResource = 0;
  317. BSTR bstrResourceName = NULL;
  318. //
  319. // create resource list
  320. //
  321. hr = THR( HrCreateResourceList() );
  322. if ( FAILED( hr ) )
  323. {
  324. goto Error;
  325. }
  326. //
  327. // get combo box handle
  328. //
  329. m_hComboBox = GetDlgItem( m_hwnd, IDC_QUORUM_CB_QUORUM );
  330. if ( m_hComboBox == NULL )
  331. {
  332. sc = TW32( GetLastError() );
  333. hr = HRESULT_FROM_WIN32( sc );
  334. goto Error;
  335. }
  336. //
  337. // fill combo box
  338. //
  339. for ( idxResource = 0 ; idxResource < m_cValidResources ; idxResource++ )
  340. {
  341. hr = THR( m_rgpResources[ idxResource ]->GetName( &bstrResourceName ) );
  342. if ( FAILED( hr ) )
  343. {
  344. goto Error;
  345. }
  346. TraceMemoryAddBSTR( bstrResourceName );
  347. sc = (DWORD) SendMessage( m_hComboBox, CB_ADDSTRING, 0, reinterpret_cast<LPARAM>( bstrResourceName ) );
  348. if ( ( sc == CB_ERR ) || ( sc == CB_ERRSPACE ) )
  349. {
  350. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  351. goto Error;
  352. }
  353. TraceSysFreeString( bstrResourceName );
  354. bstrResourceName = NULL;
  355. // - remember which is quorum resource
  356. hr = STHR( m_rgpResources[ idxResource ]->IsQuorumResource() );
  357. if ( FAILED( hr ) )
  358. {
  359. goto Error;
  360. }
  361. else if ( hr == S_OK )
  362. {
  363. m_idxQuorumResource = idxResource;
  364. m_fQuorumAlreadySet = true;
  365. }
  366. } // for: each resource
  367. //
  368. // set combo box selection to current quorum resource
  369. //
  370. sc = (DWORD) SendMessage( m_hComboBox, CB_SETCURSEL, m_idxQuorumResource, 0 );
  371. if ( sc == CB_ERR )
  372. {
  373. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  374. goto Error;
  375. }
  376. //
  377. // Update the buttons based on what is selected.
  378. //
  379. UpdateButtons();
  380. //
  381. // Set focus to the combo box.
  382. //
  383. SetFocus( m_hComboBox );
  384. goto Cleanup;
  385. Error:
  386. HrMessageBoxWithStatus(
  387. m_hwnd
  388. , IDS_ERR_RESOURCE_GATHER_FAILURE_TITLE
  389. , IDS_ERR_RESOURCE_GATHER_FAILURE_TEXT
  390. , hr
  391. , 0
  392. , MB_OK | MB_ICONERROR
  393. , 0
  394. );
  395. EndDialog( m_hwnd, IDCANCEL ); // show message box?
  396. lr = FALSE;
  397. goto Cleanup;
  398. Cleanup:
  399. TraceSysFreeString( bstrResourceName );
  400. RETURN( lr );
  401. } //*** CQuorumDlg::OnInitDialog
  402. //////////////////////////////////////////////////////////////////////////////
  403. //++
  404. //
  405. // CQuorumDlg::OnCommand
  406. //
  407. // Description:
  408. // Handler for the WM_COMMAND message.
  409. //
  410. // Arguments:
  411. // idNotificationIn - Notification code.
  412. // idControlIn - Control ID.
  413. // hwndSenderIn - Handle for the window that sent the message.
  414. //
  415. // Return Values:
  416. // TRUE - Message has been handled.
  417. // FALSE - Message has not been handled yet.
  418. //
  419. //--
  420. //////////////////////////////////////////////////////////////////////////////
  421. LRESULT
  422. CQuorumDlg::OnCommand(
  423. UINT idNotificationIn
  424. , UINT idControlIn
  425. , HWND hwndSenderIn
  426. )
  427. {
  428. TraceFunc( "" );
  429. LRESULT lr = FALSE;
  430. size_t idxCurrentSelection = 0;
  431. HRESULT hr = S_OK;
  432. BOOL fState;
  433. IClusCfgManagedResourceInfo * pQuorum = NULL;
  434. IClusCfgManagedResourceInfo * pCurrent = NULL;
  435. BSTR bstrTemp = NULL;
  436. BOOL bLocalQuorum;
  437. switch ( idControlIn )
  438. {
  439. case IDOK:
  440. //
  441. // get selection from combo box
  442. //
  443. idxCurrentSelection = SendMessage( m_hComboBox, CB_GETCURSEL, 0, 0 );
  444. if ( idxCurrentSelection == CB_ERR )
  445. {
  446. hr = HRESULT_FROM_WIN32( TW32( (DWORD) CB_ERR ) );
  447. goto Error;
  448. }
  449. //
  450. // if original quorum resource is different, or had not been set.
  451. //
  452. if ( ( idxCurrentSelection != m_idxQuorumResource ) || !m_fQuorumAlreadySet )
  453. {
  454. pQuorum = m_rgpResources[ m_idxQuorumResource ];
  455. pCurrent = m_rgpResources[ idxCurrentSelection ];
  456. //
  457. // First, is the new resource Local Quorum? (Special processing -
  458. // unfortunate but necessary.)
  459. //
  460. hr = THR( pCurrent->GetUID( &bstrTemp ) );
  461. if ( FAILED( hr ) )
  462. {
  463. goto Error;
  464. } // if:
  465. bLocalQuorum = ( NStringCchCompareCase( bstrTemp, SysStringLen( bstrTemp ) + 1, CLUS_RESTYPE_NAME_LKQUORUM, RTL_NUMBER_OF( CLUS_RESTYPE_NAME_LKQUORUM ) ) == 0 );
  466. SysFreeString( bstrTemp );
  467. bstrTemp = NULL;
  468. //
  469. // Clear original quorum resource.
  470. //
  471. hr = THR( pQuorum->SetQuorumResource( FALSE ) );
  472. //
  473. // Set the managed state back to it's original state.
  474. //
  475. if ( SUCCEEDED( hr ) )
  476. {
  477. fState = m_pssa->prsArray[ m_idxQuorumResource ].fState;
  478. hr = THR( pQuorum->SetManaged( fState ) );
  479. } // if:
  480. //
  481. // If we successfully ran PrepareToHostQuorum on this resource the last time
  482. // this dialog was up we now need to clean it up.
  483. //
  484. if ( m_pssa->prsArray[ m_idxQuorumResource ].fNeedCleanup )
  485. {
  486. THR( HrCleanupQuorumResource( pQuorum ) );
  487. } // if:
  488. //
  489. // Set new quorum resource.
  490. //
  491. if ( SUCCEEDED( hr ) )
  492. {
  493. //
  494. // This function returns S_FALSE when the resource does not support
  495. // the IClusCfgVerifyQuorum interface. If the resource doesn't
  496. // support the interface then there is no need to clean it up later.
  497. //
  498. hr = STHR( HrInitQuorumResource( pCurrent ) );
  499. if ( FAILED( hr ) )
  500. {
  501. goto Error;
  502. } // if:
  503. if ( hr == S_OK )
  504. {
  505. m_pssa->prsArray[ idxCurrentSelection ].fNeedCleanup = TRUE;
  506. hr = THR( pCurrent->SetQuorumResource( TRUE ) );
  507. } // if:
  508. } // if:
  509. //
  510. // Local Quorum resources should never be SetManaged( TRUE ).
  511. //
  512. if ( SUCCEEDED( hr ) && !bLocalQuorum )
  513. {
  514. hr = THR( m_rgpResources[ idxCurrentSelection ]->SetManaged( TRUE ) );
  515. } // if:
  516. if ( FAILED( hr ) )
  517. {
  518. fState = m_pssa->prsArray[ idxCurrentSelection ].fState;
  519. THR( pCurrent->SetManaged( fState ) );
  520. THR( pCurrent->SetQuorumResource( FALSE ) );
  521. THR( pQuorum->SetQuorumResource( TRUE ) );
  522. THR( pQuorum->SetManaged( bLocalQuorum == FALSE ) );
  523. goto Error;
  524. } // if:
  525. EndDialog( m_hwnd, IDOK );
  526. }
  527. else // (combo box selection is same as original)
  528. {
  529. EndDialog( m_hwnd, IDCANCEL );
  530. }
  531. break;
  532. case IDCANCEL:
  533. EndDialog( m_hwnd, IDCANCEL );
  534. break;
  535. case IDHELP:
  536. HtmlHelp( m_hwnd, L"mscsconcepts.chm::/SAG_MSCS2planning_6.htm", HH_DISPLAY_TOPIC, 0 );
  537. break;
  538. } // switch: idControlIn
  539. goto Cleanup;
  540. Error:
  541. HrMessageBoxWithStatus(
  542. m_hwnd
  543. , IDS_ERR_QUORUM_COMMIT_FAILURE_TITLE
  544. , IDS_ERR_QUORUM_COMMIT_FAILURE_TEXT
  545. , hr
  546. , 0
  547. , MB_OK | MB_ICONERROR
  548. , 0
  549. );
  550. goto Cleanup;
  551. Cleanup:
  552. RETURN( lr );
  553. } //*** CQuorumDlg::OnCommand
  554. //////////////////////////////////////////////////////////////////////////////
  555. //++
  556. //
  557. // CQuorumDlg::HrCreateResourceList
  558. //
  559. // Description:
  560. // Allocates and fills m_rgpResources array with quorum capable and
  561. // joinable resources, and sets m_idxQuorumResource to the index of the
  562. // resource that's currently the quorum resource.
  563. //
  564. // Supposedly at least one quorum capable and joinable resource always
  565. // exists, and exactly one is marked as the quorum resource.
  566. //
  567. // Arguments:
  568. // None.
  569. //
  570. // Return Values:
  571. // S_OK - Success.
  572. // S_FALSE - Didn't find current quorum resource.
  573. // E_OUTOFMEMORY - Couldn't allocate memory for the list.
  574. //
  575. // Other possible error values from called methods.
  576. //
  577. //--
  578. //////////////////////////////////////////////////////////////////////////////
  579. HRESULT
  580. CQuorumDlg::HrCreateResourceList( void )
  581. {
  582. TraceFunc( "" );
  583. HRESULT hr = S_OK;
  584. IUnknown * punkEnum = NULL;
  585. IEnumClusCfgManagedResources * peccmr = NULL;
  586. DWORD idxResCurrent = 0;
  587. ULONG cFetchedResources = 0;
  588. DWORD cTotalResources = 0;
  589. BOOL fState;
  590. Assert( m_pccw != NULL );
  591. //
  592. // get resource enumerator
  593. //
  594. hr = THR( m_pccw->HrGetClusterChild( CLSID_ManagedResourceType, DFGUID_EnumManageableResources, &punkEnum ) );
  595. if ( FAILED( hr ) )
  596. {
  597. goto Cleanup;
  598. }
  599. hr = THR( punkEnum->TypeSafeQI( IEnumClusCfgManagedResources, &peccmr ) );
  600. if ( FAILED( hr ) )
  601. {
  602. goto Cleanup;
  603. }
  604. //
  605. // find out how many resources exist
  606. //
  607. hr = THR( peccmr->Count( &cTotalResources ) );
  608. if ( FAILED( hr ) )
  609. {
  610. goto Cleanup;
  611. }
  612. //
  613. // allocate memory for resources
  614. //
  615. m_rgpResources = new IClusCfgManagedResourceInfo*[ cTotalResources ];
  616. if ( m_rgpResources == NULL )
  617. {
  618. hr = THR( E_OUTOFMEMORY );
  619. goto Cleanup;
  620. }
  621. for ( idxResCurrent = 0 ; idxResCurrent < cTotalResources ; idxResCurrent++ )
  622. {
  623. m_rgpResources[ idxResCurrent ] = NULL;
  624. }
  625. //
  626. // allocate the m_pssa arrays
  627. //
  628. if ( m_pssa->bInitialized == FALSE )
  629. {
  630. m_pssa->prsArray = new SResourceState[ cTotalResources ];
  631. if ( m_pssa->prsArray == NULL )
  632. {
  633. hr = THR( E_OUTOFMEMORY );
  634. goto Cleanup;
  635. }
  636. for ( idxResCurrent = 0 ; idxResCurrent < cTotalResources ; idxResCurrent++ )
  637. {
  638. m_pssa->prsArray[ idxResCurrent ].fState = FALSE;
  639. m_pssa->prsArray[ idxResCurrent ].fNeedCleanup = FALSE;
  640. }
  641. } // if: m_pssa ! already initialized
  642. //
  643. // copy resources into array
  644. //
  645. hr = THR( peccmr->Next( cTotalResources, m_rgpResources, &cFetchedResources ) );
  646. if ( FAILED( hr ) )
  647. {
  648. goto Cleanup;
  649. }
  650. Assert( cFetchedResources == cTotalResources ); // if not, something's wrong with the enum
  651. cTotalResources = min( cTotalResources, cFetchedResources ); // playing it safe
  652. //
  653. // filter out invalid resources
  654. //
  655. for ( idxResCurrent = 0 ; idxResCurrent < cTotalResources ; idxResCurrent++ )
  656. {
  657. if ( !FIsValidResource( m_rgpResources[ idxResCurrent ] ) )
  658. {
  659. m_rgpResources[ idxResCurrent ]->Release();
  660. m_rgpResources[ idxResCurrent ] = NULL;
  661. }
  662. }
  663. //
  664. // compact array; might leave some non-null pointers after end,
  665. // so always use m_cValidResources to determine length hereafter
  666. //
  667. for ( idxResCurrent = 0 ; idxResCurrent < cTotalResources ; idxResCurrent++ )
  668. {
  669. if ( m_rgpResources[ idxResCurrent ] != NULL )
  670. {
  671. m_rgpResources[ m_cValidResources ] = m_rgpResources[ idxResCurrent ];
  672. if ( m_pssa->bInitialized == FALSE )
  673. {
  674. fState = ( m_rgpResources[ m_cValidResources ]->IsManaged() == S_OK ) ? TRUE : FALSE;
  675. m_pssa->prsArray[ m_cValidResources ].fState = fState;
  676. }
  677. m_cValidResources++;
  678. } // if: current element !NULL
  679. } // for: compact the array
  680. if ( m_pssa->bInitialized == FALSE )
  681. {
  682. m_pssa->cCount = m_cValidResources;
  683. m_pssa->bInitialized = TRUE;
  684. }
  685. Cleanup:
  686. if ( m_pssa->bInitialized == FALSE )
  687. {
  688. delete [] m_pssa->prsArray;
  689. m_pssa->prsArray = NULL;
  690. m_pssa->cCount = 0;
  691. }
  692. if ( punkEnum != NULL )
  693. {
  694. punkEnum->Release();
  695. }
  696. if ( peccmr != NULL )
  697. {
  698. peccmr->Release();
  699. }
  700. HRETURN( hr );
  701. } //*** CQuorumDlg::HrCreateResourceList
  702. //////////////////////////////////////////////////////////////////////////////
  703. //++
  704. //
  705. // CQuorumDlg::UpdateButtons
  706. //
  707. // Description:
  708. // Update the OK and Cancel buttons.
  709. //
  710. // Arguments:
  711. // None.
  712. //
  713. // Return Values:
  714. // None.
  715. //
  716. //--
  717. //////////////////////////////////////////////////////////////////////////////
  718. void
  719. CQuorumDlg::UpdateButtons( void )
  720. {
  721. TraceFunc( "" );
  722. BOOL fEnableOK;
  723. LRESULT lrCurSel;
  724. lrCurSel = SendMessage( GetDlgItem( m_hwnd, IDC_QUORUM_CB_QUORUM ), CB_GETCURSEL, 0, 0 );
  725. fEnableOK = ( lrCurSel != CB_ERR );
  726. EnableWindow( GetDlgItem( m_hwnd, IDOK ), fEnableOK );
  727. TraceFuncExit();
  728. } //*** CQuorumDlg::UpdateButtons
  729. //////////////////////////////////////////////////////////////////////////////
  730. //++
  731. //
  732. // CDetailsDlg::HrInitQuorumResource
  733. //
  734. // Description:
  735. // Initialize the just chosen quorum resource.
  736. //
  737. // Arguments:
  738. // pResourceIn
  739. // The resource that was chosen as the quorum.
  740. //
  741. // Return Values:
  742. // S_OK
  743. // Success.
  744. //
  745. // Other HRESULT failures.
  746. //
  747. //--
  748. //////////////////////////////////////////////////////////////////////////////
  749. HRESULT
  750. CQuorumDlg::HrInitQuorumResource(
  751. IClusCfgManagedResourceInfo * pResourceIn
  752. )
  753. {
  754. TraceFunc( "" );
  755. Assert( pResourceIn != NULL );
  756. HRESULT hr = S_OK;
  757. IClusCfgVerifyQuorum * piccvq = NULL;
  758. BSTR bstrResource = NULL;
  759. //
  760. // Does this resource implement the IClusCfgVerifyQuorum interface?
  761. //
  762. hr = pResourceIn->TypeSafeQI( IClusCfgVerifyQuorum, &piccvq );
  763. if ( hr == E_NOINTERFACE )
  764. {
  765. hr = S_FALSE;
  766. goto Cleanup;
  767. } // if:
  768. else if ( FAILED( hr ) )
  769. {
  770. goto Cleanup;
  771. } // else if:
  772. hr = THR( pResourceIn->GetName( &bstrResource ) );
  773. if ( FAILED( hr ) )
  774. {
  775. bstrResource = TraceSysAllocString( L"<unknown>" );
  776. } // if:
  777. else
  778. {
  779. TraceMemoryAddBSTR( bstrResource );
  780. } // else:
  781. //
  782. // The resource did implement the IClusCfgVerifyQuorum interface...
  783. //
  784. Assert( ( hr == S_OK ) && ( piccvq != NULL ) );
  785. hr = STHR( piccvq->PrepareToHostQuorumResource() );
  786. if ( FAILED( hr ) )
  787. {
  788. LogMsg( L"[WIZ] PrepareToHostQuorum() failed for resource %ws. (hr = %#08x)", bstrResource, hr );
  789. goto Cleanup;
  790. } // if:
  791. Cleanup:
  792. TraceSysFreeString( bstrResource );
  793. if ( piccvq != NULL )
  794. {
  795. piccvq->Release();
  796. } // if:
  797. HRETURN( hr );
  798. } //*** CQuorumDlg::HrInitQuorumResource
  799. //////////////////////////////////////////////////////////////////////////////
  800. //++
  801. //
  802. // CDetailsDlg::HrCleanupQuorumResource
  803. //
  804. // Description:
  805. // Cleanup the passed in quorum resource.
  806. //
  807. // Arguments:
  808. // pResourceIn
  809. // The resource that used to be selected as the quorum.
  810. //
  811. // Return Values:
  812. // S_OK
  813. // Success.
  814. //
  815. // Other HRESULT failures.
  816. //
  817. //--
  818. //////////////////////////////////////////////////////////////////////////////
  819. HRESULT
  820. CQuorumDlg::HrCleanupQuorumResource(
  821. IClusCfgManagedResourceInfo * pResourceIn
  822. )
  823. {
  824. TraceFunc( "" );
  825. Assert( pResourceIn != NULL );
  826. HRESULT hr = S_OK;
  827. IClusCfgVerifyQuorum * piccvq = NULL;
  828. BSTR bstrResource = NULL;
  829. //
  830. // Does this resource implement the IClusCfgVerifyQuorum interface?
  831. //
  832. hr = pResourceIn->TypeSafeQI( IClusCfgVerifyQuorum, &piccvq );
  833. if ( hr == E_NOINTERFACE )
  834. {
  835. hr = S_OK;
  836. goto Cleanup;
  837. } // if:
  838. else if ( FAILED( hr ) )
  839. {
  840. goto Cleanup;
  841. } // else if:
  842. hr = THR( pResourceIn->GetName( &bstrResource ) );
  843. if ( FAILED( hr ) )
  844. {
  845. bstrResource = TraceSysAllocString( L"<unknown>" );
  846. } // if:
  847. else
  848. {
  849. TraceMemoryAddBSTR( bstrResource );
  850. } // else:
  851. //
  852. // The resource did implement the IClusCfgVerifyQuorum interface...
  853. //
  854. Assert( ( hr == S_OK ) && ( piccvq != NULL ) );
  855. hr = STHR( piccvq->Cleanup( crCANCELLED ) );
  856. if ( FAILED( hr ) )
  857. {
  858. LogMsg( L"[WIZ] Cleanup() failed for resource %ws. (hr = %#08x)", bstrResource, hr );
  859. goto Cleanup;
  860. } // if:
  861. Cleanup:
  862. TraceSysFreeString( bstrResource );
  863. if ( piccvq != NULL )
  864. {
  865. piccvq->Release();
  866. } // if:
  867. HRETURN( hr );
  868. } //*** CQuorumDlg::HrCleanupQuorumResource