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.

3856 lines
94 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ClusCfg.cpp
  7. //
  8. // Description:
  9. // Implementation of CClusCfgWizard class.
  10. //
  11. // Maintained By:
  12. // David Potter (DavidP) 14-MAR-2001
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. //////////////////////////////////////////////////////////////////////////////
  16. // Include Files
  17. //////////////////////////////////////////////////////////////////////////////
  18. #include "Pch.h"
  19. #include "TaskTreeView.h"
  20. #include "AnalyzePage.h"
  21. #include "ClusDomainPage.h"
  22. #include "CommitPage.h"
  23. #include "CompletionPage.h"
  24. #include "CSAccountPage.h"
  25. #include "IPAddressPage.h"
  26. #include "SelNodePage.h"
  27. #include "SelNodesPage.h"
  28. #include "WelcomePage.h"
  29. #include "SummaryPage.h"
  30. #include <initguid.h>
  31. //****************************************************************************
  32. //
  33. // CClusCfgWizard
  34. //
  35. //****************************************************************************
  36. DEFINE_THISCLASS( "CClusCfgWizard" )
  37. // {AAA8DA17-62C8-40f6-BEC1-3F0326B73388}
  38. DEFINE_GUID( CLSID_CancelCleanupTaskCompletionCookieType,
  39. 0xaaa8da17, 0x62c8, 0x40f6, 0xbe, 0xc1, 0x3f, 0x3, 0x26, 0xb7, 0x33, 0x88 );
  40. //////////////////////////////////////////////////////////////////////////////
  41. //++
  42. //
  43. // CClusCfgWizard::S_HrCreateInstance
  44. //
  45. // Description:
  46. // Create a CClusCfgWizard instance.
  47. //
  48. // Arguments:
  49. // ppccwOut
  50. //
  51. // Return Values:
  52. // S_OK - Operation completed successfully.
  53. // E_OUTOFMEMORY - Error allocating memory.
  54. // Other HRESULTs.
  55. //
  56. //--
  57. //////////////////////////////////////////////////////////////////////////////
  58. HRESULT
  59. CClusCfgWizard::S_HrCreateInstance(
  60. CClusCfgWizard ** ppccwOut
  61. )
  62. {
  63. TraceFunc( "" );
  64. HRESULT hr = S_OK;
  65. CClusCfgWizard * pccw = NULL;
  66. Assert( ppccwOut != NULL );
  67. if ( ppccwOut == NULL )
  68. {
  69. hr = THR( E_POINTER );
  70. goto Cleanup;
  71. }
  72. *ppccwOut = NULL;
  73. pccw = new CClusCfgWizard();
  74. if ( pccw == NULL )
  75. {
  76. hr = THR( E_OUTOFMEMORY );
  77. goto Cleanup;
  78. }
  79. hr = THR( pccw->HrInit() );
  80. if ( FAILED( hr ) )
  81. {
  82. goto Cleanup;
  83. }
  84. *ppccwOut = pccw;
  85. pccw = NULL;
  86. Cleanup:
  87. if ( pccw != NULL )
  88. {
  89. pccw->Release();
  90. }
  91. HRETURN( hr );
  92. } //*** CClusCfgWizard::S_HrCreateInstance
  93. //////////////////////////////////////////////////////////////////////////////
  94. //++
  95. //
  96. // CClusCfgWizard::CClusCfgWizard
  97. //
  98. // Description:
  99. // Default constructor.
  100. //
  101. // Arguments:
  102. // None.
  103. //
  104. // Return Values:
  105. // None.
  106. //
  107. //--
  108. //////////////////////////////////////////////////////////////////////////////
  109. CClusCfgWizard::CClusCfgWizard( void )
  110. : m_cRef( 1 )
  111. , m_pccc( NULL )
  112. , m_psp( NULL )
  113. , m_pcpc( NULL )
  114. , m_pom( NULL )
  115. , m_ptm( NULL )
  116. , m_bstrClusterDomain( NULL )
  117. , m_fDefaultedDomain( TRUE )
  118. , m_dwCookieNotify( 0 )
  119. , m_hCancelCleanupEvent( NULL )
  120. {
  121. TraceFunc( "" );
  122. TraceFuncExit();
  123. } //*** CClusCfgWizard::CClusCfgWizard
  124. //////////////////////////////////////////////////////////////////////////////
  125. //++
  126. //
  127. // CClusCfgWizard::~CClusCfgWizard
  128. //
  129. // Description:
  130. // Destructor.
  131. //
  132. // Arguments:
  133. // None.
  134. //
  135. // Return Values:
  136. // None.
  137. //
  138. //--
  139. //////////////////////////////////////////////////////////////////////////////
  140. CClusCfgWizard::~CClusCfgWizard( void )
  141. {
  142. TraceFunc( "" );
  143. TraceSysFreeString( m_bstrNetworkName );
  144. TraceSysFreeString( m_bstrClusterDomain );
  145. if ( m_psp != NULL )
  146. {
  147. m_psp->Release();
  148. } // if:
  149. if ( m_pcpc != NULL )
  150. {
  151. m_pcpc->Release();
  152. } // if:
  153. if ( m_ptm != NULL )
  154. {
  155. m_ptm->Release();
  156. } // if:
  157. if ( m_pom != NULL )
  158. {
  159. m_pom->Release();
  160. } // if:
  161. if ( m_pccc != NULL )
  162. {
  163. m_pccc->Release();
  164. } // if:
  165. if ( m_hRichEdit != NULL )
  166. {
  167. FreeLibrary( m_hRichEdit );
  168. } // if:
  169. if ( m_hCancelCleanupEvent != NULL )
  170. {
  171. CloseHandle( m_hCancelCleanupEvent );
  172. } // if:
  173. TraceFuncExit();
  174. } // ~CClusCfgWizard
  175. //////////////////////////////////////////////////////////////////////////////
  176. //++
  177. //
  178. // CClusCfgWizard::HrInit
  179. //
  180. // Description:
  181. // Initialize a CClusCfgWizard instance.
  182. //
  183. // Arguments:
  184. // None.
  185. //
  186. // Return Values:
  187. // S_OK - Operation completed successfully.
  188. // Other HRESULTs.
  189. //
  190. //--
  191. //////////////////////////////////////////////////////////////////////////////
  192. HRESULT
  193. CClusCfgWizard::HrInit( void )
  194. {
  195. HRESULT hr = S_OK;
  196. TraceFunc( "" );
  197. INITCOMMONCONTROLSEX icex;
  198. BOOL bRet;
  199. // EConfigurationSettings ecsConfigType = csFullConfig;
  200. // IUnknown
  201. Assert( m_cRef == 1 );
  202. Assert( m_ulIPAddress == 0 );
  203. Assert( m_ulIPSubnet == 0 );
  204. Assert( m_bstrNetworkName == NULL );
  205. Assert( m_psp == NULL );
  206. Assert( m_pcpc == NULL );
  207. Assert( m_pom == NULL );
  208. Assert( m_ptm == NULL );
  209. Assert( m_pccc == NULL );
  210. Assert( m_cookieCompletion == 0 );
  211. Assert( m_fMinimalConfig == FALSE );
  212. icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
  213. icex.dwICC = ICC_INTERNET_CLASSES
  214. | ICC_PROGRESS_CLASS
  215. | ICC_TREEVIEW_CLASSES
  216. | ICC_LISTVIEW_CLASSES;
  217. bRet = InitCommonControlsEx( &icex );
  218. Assert( bRet != FALSE );
  219. hr = THR( CoCreateInstance(
  220. CLSID_ServiceManager
  221. , NULL
  222. , CLSCTX_INPROC_SERVER
  223. , IID_IServiceProvider
  224. , reinterpret_cast< void ** >( &m_psp )
  225. ) );
  226. if ( FAILED( hr ) )
  227. {
  228. goto Cleanup;
  229. }
  230. hr = THR( m_psp->TypeSafeQS( CLSID_ObjectManager, IObjectManager, &m_pom ) );
  231. if ( FAILED( hr ) )
  232. {
  233. goto Cleanup;
  234. }
  235. hr = THR( m_psp->TypeSafeQS( CLSID_TaskManager, ITaskManager, &m_ptm ) );
  236. if ( FAILED( hr ) )
  237. {
  238. goto Cleanup;
  239. }
  240. hr = THR( m_psp->TypeSafeQS( CLSID_NotificationManager, IConnectionPointContainer, &m_pcpc ) );
  241. if ( FAILED( hr ) )
  242. {
  243. goto Cleanup;
  244. }
  245. hr = THR( HrCoCreateInternalInstance(
  246. CLSID_ClusCfgCredentials
  247. , NULL
  248. , CLSCTX_INPROC_SERVER
  249. , IID_IClusCfgCredentials
  250. , reinterpret_cast< void ** >( &m_pccc )
  251. ) );
  252. if ( FAILED( hr ) )
  253. {
  254. goto Cleanup;
  255. }
  256. //
  257. // Initialize the RichEdit controls.
  258. //
  259. m_hRichEdit = LoadLibrary( L"RichEd32.Dll" );
  260. if ( m_hRichEdit == NULL )
  261. {
  262. hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
  263. goto Cleanup;
  264. }
  265. m_hCancelCleanupEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
  266. if ( m_hCancelCleanupEvent == NULL )
  267. {
  268. hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
  269. goto Cleanup;
  270. } // if:
  271. // STHR( HrReadSettings( &ecsConfigType ) );
  272. // m_fMinimalConfig = ( ecsConfigType == csMinConfig );
  273. Cleanup:
  274. HRETURN( hr );
  275. } //*** CClusCfgWizard::HrInit
  276. //****************************************************************************
  277. //
  278. // IUnknown
  279. //
  280. //****************************************************************************
  281. //////////////////////////////////////////////////////////////////////////////
  282. //++
  283. //
  284. // CClusCfgWizard::QueryInterface
  285. //
  286. // Description:
  287. // Query this object for the passed in interface.
  288. //
  289. // Arguments:
  290. // riidIn
  291. // Id of interface requested.
  292. //
  293. // ppvOut
  294. // Pointer to the requested interface.
  295. //
  296. // Return Value:
  297. // S_OK
  298. // If the interface is available on this object.
  299. //
  300. // E_NOINTERFACE
  301. // If the interface is not available.
  302. //
  303. // E_POINTER
  304. // ppvOut was NULL.
  305. //
  306. // Remarks:
  307. // None.
  308. //
  309. //--
  310. //////////////////////////////////////////////////////////////////////////////
  311. STDMETHODIMP
  312. CClusCfgWizard::QueryInterface(
  313. REFIID riidIn
  314. , PVOID * ppvOut
  315. )
  316. {
  317. TraceQIFunc( riidIn, ppvOut );
  318. HRESULT hr = S_OK;
  319. //
  320. // Validate arguments.
  321. //
  322. Assert( ppvOut != NULL );
  323. if ( ppvOut == NULL )
  324. {
  325. hr = THR( E_POINTER );
  326. goto Cleanup;
  327. }
  328. //
  329. // Handle known interfaces.
  330. //
  331. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  332. {
  333. *ppvOut = static_cast< IUnknown * >( this );
  334. } // if: IUnknown
  335. else if ( IsEqualIID( riidIn, IID_INotifyUI ) )
  336. {
  337. *ppvOut = TraceInterface( __THISCLASS__, INotifyUI, this, 0 );
  338. } // else if: INotifyUI
  339. else
  340. {
  341. *ppvOut = NULL;
  342. hr = E_NOINTERFACE;
  343. } // else
  344. //
  345. // Add a reference to the interface if successful.
  346. //
  347. if ( SUCCEEDED( hr ) )
  348. {
  349. ((IUnknown *) *ppvOut)->AddRef();
  350. } // if: success
  351. Cleanup:
  352. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  353. } //*** CClusCfgWizard::QueryInterface
  354. //////////////////////////////////////////////////////////////////////////////
  355. //++
  356. //
  357. // CClusCfgWizard::AddRef
  358. //
  359. // Description:
  360. // Add a reference to this instance.
  361. //
  362. // Arguments:
  363. // None.
  364. //
  365. // Return Values:
  366. // New reference count.
  367. //
  368. //--
  369. //////////////////////////////////////////////////////////////////////////////
  370. STDMETHODIMP_( ULONG )
  371. CClusCfgWizard::AddRef( void )
  372. {
  373. TraceFunc( "[IUnknown]" );
  374. InterlockedIncrement( &m_cRef );
  375. CRETURN( m_cRef );
  376. } //*** CClusCfgWizard::AddRef
  377. //////////////////////////////////////////////////////////////////////////////
  378. //++
  379. //
  380. // CClusCfgWizard::Release
  381. //
  382. // Description:
  383. // Release a reference to this instance. If it is the last reference
  384. // the object instance will be deallocated.
  385. //
  386. // Arguments:
  387. // None.
  388. //
  389. // Return Values:
  390. // New reference count.
  391. //
  392. //--
  393. //////////////////////////////////////////////////////////////////////////////
  394. STDMETHODIMP_( ULONG )
  395. CClusCfgWizard::Release( void )
  396. {
  397. TraceFunc( "[IUnknown]" );
  398. LONG cRef;
  399. cRef = InterlockedDecrement( &m_cRef );
  400. if ( cRef == 0 )
  401. {
  402. delete this;
  403. }
  404. CRETURN( cRef );
  405. } //*** CClusCfgWizard::Release
  406. //****************************************************************************
  407. //
  408. // IClusCfgWizard
  409. //
  410. //****************************************************************************
  411. //////////////////////////////////////////////////////////////////////////////
  412. //++
  413. //
  414. // CClusCfgWizard::CreateCluster
  415. //
  416. // Description:
  417. //
  418. // Arguments:
  419. // ParentWnd
  420. // pfDone
  421. //
  422. // Return Values:
  423. //
  424. //--
  425. //////////////////////////////////////////////////////////////////////////////
  426. STDMETHODIMP
  427. CClusCfgWizard::CreateCluster(
  428. HWND lParentWndIn,
  429. BOOL * pfDoneOut
  430. )
  431. {
  432. TraceFunc( "[IClusCfgWizard]" );
  433. HPROPSHEETPAGE rPages[ 9 ];
  434. PROPSHEETHEADER pshead;
  435. BOOL fSuccess;
  436. INT_PTR ipStatus;
  437. HRESULT hr = S_OK;
  438. ILogManager * plm = NULL;
  439. TraceFlow1( "[Clcfgsrv] - CClusCfgWizard::CreateCluster - Thread id %d", GetCurrentThreadId() );
  440. CWelcomePage dlgWelcomePage( this, camCREATING );
  441. CClusDomainPage dlgClusDomainPage( this, camCREATING, IDS_DOMAIN_DESC_CREATE );
  442. CSelNodePage dlgSelNodePage( this );
  443. CAnalyzePage dlgAnalyzePage( this, camCREATING );
  444. CIPAddressPage dlgIPAddressPage( this, camCREATING, &m_ulIPAddress, &m_ulIPSubnet, &m_bstrNetworkName );
  445. CCSAccountPage dlgCSAccountPage( this, camCREATING, m_pccc );
  446. CSummaryPage dlgSummaryPage( this, camCREATING, IDS_SUMMARY_NEXT_CREATE );
  447. CCommitPage dlgCommitPage( this, camCREATING );
  448. CCompletionPage dlgCompletionPage( IDS_COMPLETION_TITLE_CREATE, IDS_COMPLETION_DESC_CREATE );
  449. //
  450. // TODO: gpease 14-MAY-2000
  451. // Do we really need this?
  452. //
  453. if ( pfDoneOut == NULL )
  454. {
  455. hr = THR( E_POINTER );
  456. goto Cleanup;
  457. } // if:
  458. //
  459. // Start the logger.
  460. //
  461. hr = THR( m_psp->TypeSafeQS( CLSID_LogManager,
  462. ILogManager,
  463. &plm
  464. ) );
  465. if ( FAILED( hr ) )
  466. goto Cleanup;
  467. hr = THR( plm->StartLogging() );
  468. if ( FAILED( hr ) )
  469. goto Cleanup;
  470. //
  471. // Register to get UI notification (if needed)
  472. //
  473. if ( m_dwCookieNotify == 0 )
  474. {
  475. hr = THR( HrAdvise( IID_INotifyUI, static_cast< INotifyUI * >( this ), &m_dwCookieNotify ) );
  476. if ( FAILED( hr ) )
  477. {
  478. goto Cleanup;
  479. } // if:
  480. } // if:
  481. //
  482. // Create the Wizard.
  483. //
  484. ZeroMemory( &pshead, sizeof( pshead ) );
  485. pshead.dwSize = sizeof( pshead );
  486. pshead.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
  487. pshead.hInstance = g_hInstance;
  488. pshead.pszCaption = MAKEINTRESOURCE( IDS_TITLE_FORM );
  489. pshead.phpage = rPages;
  490. pshead.pszbmWatermark = MAKEINTRESOURCE( IDB_WATERMARK );
  491. pshead.pszbmHeader = MAKEINTRESOURCE( IDB_BANNER );
  492. pshead.hwndParent = lParentWndIn;
  493. THR( HrAddWizardPage( &pshead, IDD_WELCOME_CREATE, CWelcomePage::S_DlgProc, 0, 0, (LPARAM) &dlgWelcomePage ) );
  494. THR( HrAddWizardPage( &pshead, IDD_CLUSDOMAIN, CClusDomainPage::S_DlgProc, IDS_TCLUSTER, IDS_STCLUSTER_CREATE, (LPARAM) &dlgClusDomainPage ) );
  495. THR( HrAddWizardPage( &pshead, IDD_SELNODE, CSelNodePage::S_DlgProc, IDS_TSELNODE, IDS_STSELNODE, (LPARAM) &dlgSelNodePage ) );
  496. THR( HrAddWizardPage( &pshead, IDD_ANALYZE, CAnalyzePage::S_DlgProc, IDS_TANALYZE, IDS_STANALYZE, (LPARAM) &dlgAnalyzePage ) );
  497. THR( HrAddWizardPage( &pshead, IDD_IPADDRESS, CIPAddressPage::S_DlgProc, IDS_TIPADDRESS, IDS_STIPADDRESS, (LPARAM) &dlgIPAddressPage ) );
  498. THR( HrAddWizardPage( &pshead, IDD_CSACCOUNT, CCSAccountPage::S_DlgProc, IDS_TCSACCOUNT, IDS_STCSACCOUNT, (LPARAM) &dlgCSAccountPage ) );
  499. THR( HrAddWizardPage( &pshead, IDD_SUMMARY, CSummaryPage::S_DlgProc, IDS_TSUMMARY, IDS_STSUMMARY_CREATE, (LPARAM) &dlgSummaryPage ) );
  500. THR( HrAddWizardPage( &pshead, IDD_COMMIT, CCommitPage::S_DlgProc, IDS_TCOMMIT_CREATE, IDS_STCOMMIT, (LPARAM) &dlgCommitPage ) );
  501. THR( HrAddWizardPage( &pshead, IDD_COMPLETION, CCompletionPage::S_DlgProc, 0, 0, (LPARAM) &dlgCompletionPage ) );
  502. AssertMsg( pshead.nPages == ARRAYSIZE( rPages ), "Not enough or too many PROPSHEETPAGEs." );
  503. ipStatus = PropertySheet( &pshead );
  504. if ( ipStatus == -1 )
  505. {
  506. TW32( GetLastError() );
  507. }
  508. fSuccess = ipStatus != NULL;
  509. if ( pfDoneOut != NULL )
  510. {
  511. *pfDoneOut = fSuccess;
  512. }
  513. Cleanup:
  514. if ( plm != NULL )
  515. {
  516. THR( plm->StopLogging() );
  517. plm->Release();
  518. } // if:
  519. if ( m_dwCookieNotify != 0 )
  520. {
  521. THR( HrUnadvise( IID_INotifyUI, m_dwCookieNotify ) );
  522. m_dwCookieNotify = 0;
  523. } // if:
  524. HRETURN( hr );
  525. } //*** CClusCfgWizard::CreateCluster
  526. //////////////////////////////////////////////////////////////////////////////
  527. //++
  528. //
  529. // CClusCfgWizard::AddClusterNodes
  530. //
  531. // Description:
  532. // Launch the Cluster Wizard in Add Cluster Nodes mode.
  533. //
  534. // Parameters
  535. // ParentWnd - Handle to the parent window (default NULL).
  536. // If not NULL, the wizard will be positionned
  537. // in the center of this window.
  538. // Done - return TRUE if committed, FALSE if cancelled.
  539. //
  540. // Return Values:
  541. // S_OK - The call succeeded.
  542. // other HRESULTs - The call failed.
  543. // E_POINTER
  544. // E_OUTOFMEMORY
  545. //
  546. //--
  547. //////////////////////////////////////////////////////////////////////////////
  548. STDMETHODIMP
  549. CClusCfgWizard::AddClusterNodes(
  550. HWND lParentWndIn,
  551. BOOL * pfDoneOut
  552. )
  553. {
  554. TraceFunc( "[IClusCfgWizard]" );
  555. HPROPSHEETPAGE rPages[ 8 ];
  556. PROPSHEETHEADER pshead;
  557. BOOL fSuccess;
  558. INT_PTR ipStatus;
  559. HRESULT hr = S_OK;
  560. ILogManager * plm = NULL;
  561. CWelcomePage dlgWelcomePage( this, camADDING );
  562. CClusDomainPage dlgClusDomainPage( this, camADDING, IDS_DOMAIN_DESC_ADD );
  563. CSelNodesPage dlgSelNodesPage( this );
  564. CAnalyzePage dlgAnalyzePage( this, camADDING );
  565. CCSAccountPage dlgCSAccountPage( this, camADDING, m_pccc );
  566. CSummaryPage dlgSummaryPage( this, camADDING, IDS_SUMMARY_NEXT_ADD );
  567. CCommitPage dlgCommitPage( this, camADDING );
  568. CCompletionPage dlgCompletionPage( IDS_COMPLETION_TITLE_ADD, IDS_COMPLETION_DESC_ADD );
  569. //
  570. // TODO: gpease 12-JUL-2000
  571. // Do we really need this? Or can we have the script implement an event
  572. // sink that we signal?
  573. //
  574. if ( pfDoneOut == NULL )
  575. {
  576. hr = THR( E_POINTER );
  577. goto Cleanup;
  578. } // if:
  579. //
  580. // Start the logger.
  581. //
  582. hr = THR( m_psp->TypeSafeQS( CLSID_LogManager,
  583. ILogManager,
  584. &plm
  585. ) );
  586. if ( FAILED( hr ) )
  587. goto Cleanup;
  588. hr = THR( plm->StartLogging() );
  589. if ( FAILED( hr ) )
  590. goto Cleanup;
  591. //
  592. // Register to get UI notification (if needed)
  593. //
  594. if ( m_dwCookieNotify == 0 )
  595. {
  596. hr = THR( HrAdvise( IID_INotifyUI, static_cast< INotifyUI * >( this ), &m_dwCookieNotify ) );
  597. if ( FAILED( hr ) )
  598. {
  599. goto Cleanup;
  600. } // if:
  601. } // if:
  602. //
  603. // Create the Wizard.
  604. //
  605. ZeroMemory( &pshead, sizeof(pshead) );
  606. pshead.dwSize = sizeof(pshead);
  607. pshead.dwFlags = PSH_WIZARD97 | PSH_WATERMARK | PSH_HEADER;
  608. pshead.hInstance = g_hInstance;
  609. pshead.pszCaption = MAKEINTRESOURCE( IDS_TITLE_JOIN );
  610. pshead.phpage = rPages;
  611. pshead.pszbmWatermark = MAKEINTRESOURCE( IDB_WATERMARK );
  612. pshead.pszbmHeader = MAKEINTRESOURCE( IDB_BANNER );
  613. pshead.hwndParent = lParentWndIn;
  614. THR( HrAddWizardPage( &pshead, IDD_WELCOME_ADD, CWelcomePage::S_DlgProc, 0, 0, (LPARAM) &dlgWelcomePage ) );
  615. THR( HrAddWizardPage( &pshead, IDD_CLUSDOMAIN, CClusDomainPage::S_DlgProc, IDS_TCLUSTER, IDS_STCLUSTER_ADD, (LPARAM) &dlgClusDomainPage ) );
  616. THR( HrAddWizardPage( &pshead, IDD_SELNODES, CSelNodesPage::S_DlgProc, IDS_TSELNODES, IDS_STSELNODES, (LPARAM) &dlgSelNodesPage ) );
  617. THR( HrAddWizardPage( &pshead, IDD_ANALYZE, CAnalyzePage::S_DlgProc, IDS_TANALYZE, IDS_STANALYZE, (LPARAM) &dlgAnalyzePage ) );
  618. THR( HrAddWizardPage( &pshead, IDD_CSACCOUNT, CCSAccountPage::S_DlgProc, IDS_TCSACCOUNT, IDS_STCSACCOUNT, (LPARAM) &dlgCSAccountPage ) );
  619. THR( HrAddWizardPage( &pshead, IDD_SUMMARY, CSummaryPage::S_DlgProc, IDS_TSUMMARY, IDS_STSUMMARY_ADD, (LPARAM) &dlgSummaryPage ) );
  620. THR( HrAddWizardPage( &pshead, IDD_COMMIT, CCommitPage::S_DlgProc, IDS_TCOMMIT_ADD, IDS_STCOMMIT, (LPARAM) &dlgCommitPage ) );
  621. THR( HrAddWizardPage( &pshead, IDD_COMPLETION, CCompletionPage::S_DlgProc, 0, 0, (LPARAM) &dlgCompletionPage ) );
  622. AssertMsg( pshead.nPages == ARRAYSIZE( rPages ), "Not enough or too many PROPSHEETPAGEs." );
  623. ipStatus = PropertySheet( &pshead );
  624. fSuccess = ipStatus != NULL;
  625. if ( pfDoneOut != NULL )
  626. {
  627. *pfDoneOut = fSuccess;
  628. }
  629. Cleanup:
  630. if ( plm != NULL )
  631. {
  632. THR( plm->StopLogging() );
  633. plm->Release();
  634. } // if:
  635. if ( m_dwCookieNotify != 0 )
  636. {
  637. THR( HrUnadvise( IID_INotifyUI, m_dwCookieNotify ) );
  638. m_dwCookieNotify = 0;
  639. } // if:
  640. HRETURN( hr );
  641. } //*** CClusCfgWizard::AddClusterNodes
  642. //////////////////////////////////////////////////////////////////////////////
  643. //++
  644. //
  645. // CClusCfgWizard::get_ClusterName
  646. //
  647. // Description:
  648. //
  649. // Arguments:
  650. // pbstrNameOut
  651. //
  652. // Return Values:
  653. //
  654. //--
  655. //////////////////////////////////////////////////////////////////////////////
  656. STDMETHODIMP
  657. CClusCfgWizard::get_ClusterName(
  658. BSTR * pbstrNameOut
  659. )
  660. {
  661. HRESULT hr = S_OK;
  662. TraceFunc( "[IClusCfgWizard]" );
  663. if ( pbstrNameOut == NULL )
  664. {
  665. hr = THR( E_POINTER );
  666. goto Cleanup;
  667. }
  668. if ( m_ncCluster.bstrName == NULL )
  669. {
  670. hr = S_FALSE;
  671. *pbstrNameOut = NULL;
  672. goto Cleanup;
  673. }
  674. // Return either an IP address or an FQDN.
  675. hr = STHR( HrIsValidFQN( m_ncCluster.bstrName, true ) );
  676. if ( hr == S_OK ) // Name is fully-qualified.
  677. {
  678. HRESULT hrFQIPTest = STHR( HrFQNIsFQIP( m_ncCluster.bstrName ) );
  679. if ( hrFQIPTest == S_OK ) // Name is an FQIP.
  680. {
  681. // If the name is an FQIP, return just the IP address.
  682. hr = HrExtractPrefixFromFQN( m_ncCluster.bstrName, pbstrNameOut );
  683. if ( FAILED( hr ) )
  684. {
  685. goto Cleanup;
  686. }
  687. TraceMemoryDelete( *pbstrNameOut, false ); // Prevent false reports of memory leaks.
  688. } // If name is FQIP.
  689. else if ( hrFQIPTest == S_FALSE ) // Name is an FQDN.
  690. {
  691. // Otherwise, the name is an FQDN, so return the whole thing.
  692. *pbstrNameOut = SysAllocString( m_ncCluster.bstrName );
  693. if ( *pbstrNameOut == NULL )
  694. {
  695. hr = THR( E_OUTOFMEMORY );
  696. goto Cleanup;
  697. }
  698. } // If name is FQDN.
  699. else if ( FAILED( hrFQIPTest ) )
  700. {
  701. hr = hrFQIPTest;
  702. goto Cleanup;
  703. }
  704. } // If name is fully-qualified.
  705. else if ( hr == S_FALSE ) // Name is not fully-qualified.
  706. {
  707. HRESULT hrIPTest = STHR( HrIsValidIPAddress( m_ncCluster.bstrName ) );
  708. if ( hrIPTest == S_OK )
  709. {
  710. // If the name is an IP address, return it.
  711. *pbstrNameOut = SysAllocString( m_ncCluster.bstrName );
  712. if ( *pbstrNameOut == NULL )
  713. {
  714. hr = THR( E_OUTOFMEMORY );
  715. goto Cleanup;
  716. }
  717. } // If name is an IP address.
  718. else if ( hrIPTest == S_FALSE ) // Name is hostname label.
  719. {
  720. // Otherwise, append the cluster domain and return the result.
  721. hr = THR( HrMakeFQN( m_ncCluster.bstrName, m_bstrClusterDomain, true, pbstrNameOut ) );
  722. if ( FAILED( hr ) )
  723. {
  724. goto Cleanup;
  725. }
  726. TraceMemoryDelete( *pbstrNameOut, false ); // Prevent false reports of memory leaks.
  727. } // If name is hostname label.
  728. else if ( FAILED( hrIPTest ) )
  729. {
  730. hr = hrIPTest;
  731. goto Cleanup;
  732. }
  733. } // If name is not fully-qualified.
  734. else if ( FAILED( hr ) )
  735. {
  736. goto Cleanup;
  737. }
  738. Cleanup:
  739. HRETURN( hr );
  740. } //*** CClusCfgWizard::get_ClusterName
  741. //////////////////////////////////////////////////////////////////////////////
  742. //++
  743. //
  744. // CClusCfgWizard::put_ClusterName
  745. //
  746. // Description:
  747. //
  748. // Arguments:
  749. // bstrNameIn
  750. //
  751. // Return Values:
  752. //
  753. //--
  754. //////////////////////////////////////////////////////////////////////////////
  755. STDMETHODIMP
  756. CClusCfgWizard::put_ClusterName(
  757. BSTR bstrNameIn
  758. )
  759. {
  760. TraceFunc1( "[IClusCfgWizard] bstrNameIn = %'ls'", bstrNameIn == NULL ? L"<null>" : bstrNameIn );
  761. HRESULT hr = S_OK;
  762. if ( bstrNameIn == NULL )
  763. {
  764. hr = THR( E_INVALIDARG );
  765. goto Cleanup;
  766. }
  767. hr = THR( HrSetClusterName( bstrNameIn, true ) );
  768. if ( FAILED( hr ) )
  769. {
  770. goto Cleanup;
  771. }
  772. Cleanup:
  773. HRETURN( hr );
  774. } //*** CClusCfgWizard::put_ClusterName
  775. //////////////////////////////////////////////////////////////////////////////
  776. //++
  777. //
  778. // CClusCfgWizard::get_ServiceAccountUserName
  779. //
  780. // Description:
  781. //
  782. // Arguments:
  783. // pbstrNameOut
  784. //
  785. // Return Values:
  786. //
  787. //--
  788. //////////////////////////////////////////////////////////////////////////////
  789. STDMETHODIMP
  790. CClusCfgWizard::get_ServiceAccountUserName(
  791. BSTR * pbstrNameOut
  792. )
  793. {
  794. TraceFunc( "[IClusCfgWizard]" );
  795. HRESULT hr = S_OK;
  796. BSTR bstrDomain = NULL;
  797. if ( pbstrNameOut == NULL )
  798. {
  799. hr = THR( E_POINTER );
  800. goto Cleanup;
  801. }
  802. hr = THR( m_pccc->GetIdentity( pbstrNameOut, &bstrDomain ) );
  803. if ( FAILED( hr ) )
  804. {
  805. goto Cleanup;
  806. }
  807. if ( SysStringLen( *pbstrNameOut ) == 0 )
  808. {
  809. hr = S_FALSE;
  810. }
  811. Cleanup:
  812. SysFreeString( bstrDomain );
  813. HRETURN( hr );
  814. } //*** CClusCfgWizard::get_ServiceAccountUserName
  815. //////////////////////////////////////////////////////////////////////////////
  816. //++
  817. //
  818. // CClusCfgWizard::put_ServiceAccountUserName
  819. //
  820. // Description:
  821. //
  822. // Arguments:
  823. // bstrNameIn
  824. //
  825. // Return Values:
  826. //
  827. //--
  828. //////////////////////////////////////////////////////////////////////////////
  829. STDMETHODIMP
  830. CClusCfgWizard::put_ServiceAccountUserName(
  831. BSTR bstrNameIn
  832. )
  833. {
  834. TraceFunc1( "[IClusCfgWizard] bstrNameIn = '%ls'", bstrNameIn == NULL ? L"<null>" : bstrNameIn );
  835. HRESULT hr = S_OK;
  836. hr = THR( m_pccc->SetCredentials( bstrNameIn, NULL, NULL ) );
  837. if ( FAILED( hr ) )
  838. {
  839. goto Cleanup;
  840. }
  841. Cleanup:
  842. HRETURN( hr );
  843. } //*** CClusCfgWizard::put_ServiceAccountUserName
  844. //////////////////////////////////////////////////////////////////////////////
  845. //++
  846. //
  847. // CClusCfgWizard::put_ServiceAccountPassword
  848. //
  849. // Description:
  850. //
  851. // Arguments:
  852. // bstrPasswordIn
  853. //
  854. // Return Values:
  855. //
  856. //--
  857. //////////////////////////////////////////////////////////////////////////////
  858. STDMETHODIMP
  859. CClusCfgWizard::put_ServiceAccountPassword(
  860. BSTR bstrPasswordIn
  861. )
  862. {
  863. TraceFunc( "[IClusCfgWizard]" );
  864. HRESULT hr = S_OK;
  865. hr = THR( m_pccc->SetCredentials( NULL, NULL, bstrPasswordIn ) );
  866. if ( FAILED( hr ) )
  867. {
  868. goto Cleanup;
  869. }
  870. Cleanup:
  871. HRETURN( hr );
  872. } //*** CClusCfgWizard::put_ServiceAccountPassword
  873. //////////////////////////////////////////////////////////////////////////////
  874. //++
  875. //
  876. // CClusCfgWizard::get_ServiceAccountDomainName
  877. //
  878. // Description:
  879. //
  880. // Arguments:
  881. // pbstrDomainOut
  882. //
  883. // Return Values:
  884. //
  885. //--
  886. //////////////////////////////////////////////////////////////////////////////
  887. STDMETHODIMP
  888. CClusCfgWizard::get_ServiceAccountDomainName(
  889. BSTR * pbstrDomainOut
  890. )
  891. {
  892. TraceFunc( "[IClusCfgWizard]" );
  893. HRESULT hr = S_OK;
  894. BSTR bstrName = NULL;
  895. if ( pbstrDomainOut == NULL )
  896. {
  897. hr = THR( E_POINTER );
  898. goto Cleanup;
  899. }
  900. hr = THR( m_pccc->GetIdentity( &bstrName, pbstrDomainOut ) );
  901. if ( FAILED( hr ) )
  902. {
  903. goto Cleanup;
  904. }
  905. if ( SysStringLen( *pbstrDomainOut ) == 0 )
  906. {
  907. hr = S_FALSE;
  908. }
  909. Cleanup:
  910. SysFreeString( bstrName );
  911. HRETURN( hr );
  912. } //*** CClusCfgWizard::get_ServiceAccountDomainName
  913. //////////////////////////////////////////////////////////////////////////////
  914. //++
  915. //
  916. // CClusCfgWizard::put_ServiceAccountDomainName
  917. //
  918. // Description:
  919. //
  920. // Arguments:
  921. // bstrDomainIn
  922. //
  923. // Return Values:
  924. //
  925. //--
  926. //////////////////////////////////////////////////////////////////////////////
  927. STDMETHODIMP
  928. CClusCfgWizard::put_ServiceAccountDomainName(
  929. BSTR bstrDomainIn
  930. )
  931. {
  932. TraceFunc1( "[IClusCfgWizard] bstrDomainIn = '%ls'", bstrDomainIn == NULL ? L"<null>" : bstrDomainIn );
  933. HRESULT hr = S_OK;
  934. hr = THR( m_pccc->SetCredentials( NULL, bstrDomainIn, NULL ) );
  935. if ( FAILED( hr ) )
  936. {
  937. goto Cleanup;
  938. }
  939. Cleanup:
  940. HRETURN( hr );
  941. } //*** CClusCfgWizard::put_ServiceAccountDomainName
  942. //////////////////////////////////////////////////////////////////////////////
  943. //++
  944. //
  945. // CClusCfgWizard::get_ClusterIPAddress
  946. //
  947. // Description:
  948. //
  949. // Arguments:
  950. // pbstrIPAddressOut
  951. //
  952. // Return Values:
  953. //
  954. //--
  955. //////////////////////////////////////////////////////////////////////////////
  956. STDMETHODIMP
  957. CClusCfgWizard::get_ClusterIPAddress(
  958. BSTR * pbstrIPAddressOut
  959. )
  960. {
  961. TraceFunc( "[IClusCfgWizard]" );
  962. HRESULT hr = S_OK;
  963. DWORD dwStatus;
  964. LPWSTR pwszIPAddress = NULL;
  965. if ( pbstrIPAddressOut == NULL )
  966. {
  967. hr = THR( E_POINTER );
  968. goto Cleanup;
  969. }
  970. if ( m_ulIPAddress == 0 )
  971. {
  972. hr = S_FALSE;
  973. *pbstrIPAddressOut = NULL;
  974. goto Cleanup;
  975. }
  976. dwStatus = TW32( ClRtlTcpipAddressToString( m_ulIPAddress, &pwszIPAddress ) );
  977. if ( dwStatus != ERROR_SUCCESS )
  978. {
  979. hr = HRESULT_FROM_WIN32( dwStatus );
  980. goto Cleanup;
  981. }
  982. *pbstrIPAddressOut = SysAllocString( pwszIPAddress );
  983. if ( *pbstrIPAddressOut == NULL )
  984. {
  985. hr = THR( E_OUTOFMEMORY );
  986. goto Cleanup;
  987. }
  988. Cleanup:
  989. if ( pwszIPAddress != NULL )
  990. {
  991. LocalFree( pwszIPAddress );
  992. }
  993. HRETURN( hr );
  994. } //*** CClusCfgWizard::get_ClusterIPAddress
  995. //////////////////////////////////////////////////////////////////////////////
  996. //++
  997. //
  998. // CClusCfgWizard::put_ClusterIPAddress
  999. //
  1000. // Description:
  1001. //
  1002. // Arguments:
  1003. // bstrIPAddressIn
  1004. //
  1005. // Return Values:
  1006. //
  1007. //--
  1008. //////////////////////////////////////////////////////////////////////////////
  1009. STDMETHODIMP
  1010. CClusCfgWizard::put_ClusterIPAddress(
  1011. BSTR bstrIPAddressIn
  1012. )
  1013. {
  1014. TraceFunc1( "[IClusCfgWizard] bstrIPAddressIn = '%ls'", bstrIPAddressIn == NULL ? L"<null>" : bstrIPAddressIn );
  1015. HRESULT hr = S_OK;
  1016. DWORD dwStatus;
  1017. if ( bstrIPAddressIn == NULL )
  1018. {
  1019. hr = THR( E_INVALIDARG );
  1020. goto Cleanup;
  1021. }
  1022. dwStatus = TW32( ClRtlTcpipStringToAddress( bstrIPAddressIn, &m_ulIPAddress ) );
  1023. if ( dwStatus != ERROR_SUCCESS )
  1024. {
  1025. hr = HRESULT_FROM_WIN32( dwStatus );
  1026. goto Cleanup;
  1027. }
  1028. Cleanup:
  1029. HRETURN( hr );
  1030. } //*** CClusCfgWizard::put_ClusterIPAddress
  1031. //////////////////////////////////////////////////////////////////////////////
  1032. //++
  1033. //
  1034. // CClusCfgWizard::get_ClusterIPSubnet
  1035. //
  1036. // Description:
  1037. //
  1038. // Arguments:
  1039. // pbstrIPSubnetOut
  1040. //
  1041. // Return Values:
  1042. //
  1043. //--
  1044. //////////////////////////////////////////////////////////////////////////////
  1045. STDMETHODIMP
  1046. CClusCfgWizard::get_ClusterIPSubnet(
  1047. BSTR * pbstrIPSubnetOut
  1048. )
  1049. {
  1050. TraceFunc( "[IClusCfgWizard]" );
  1051. HRESULT hr = S_OK;
  1052. DWORD dwStatus = ERROR_SUCCESS;
  1053. LPWSTR pwszIPSubnet = NULL;
  1054. if ( pbstrIPSubnetOut == NULL )
  1055. {
  1056. hr = THR( E_POINTER );
  1057. goto Cleanup;
  1058. }
  1059. *pbstrIPSubnetOut = NULL;
  1060. if ( m_ulIPSubnet == 0 )
  1061. {
  1062. hr = S_FALSE;
  1063. goto Cleanup;
  1064. }
  1065. dwStatus = TW32( ClRtlTcpipAddressToString( m_ulIPSubnet, &pwszIPSubnet ) );
  1066. if ( dwStatus != ERROR_SUCCESS )
  1067. {
  1068. hr = HRESULT_FROM_WIN32( dwStatus );
  1069. goto Cleanup;
  1070. }
  1071. *pbstrIPSubnetOut = SysAllocString( pwszIPSubnet );
  1072. if ( *pbstrIPSubnetOut == NULL )
  1073. {
  1074. hr = THR( E_OUTOFMEMORY );
  1075. goto Cleanup;
  1076. }
  1077. Cleanup:
  1078. if ( pwszIPSubnet != NULL )
  1079. {
  1080. LocalFree( pwszIPSubnet );
  1081. }
  1082. HRETURN( hr );
  1083. } //*** CClusCfgWizard::get_ClusterIPSubnet
  1084. //////////////////////////////////////////////////////////////////////////////
  1085. //++
  1086. //
  1087. // CClusCfgWizard::put_ClusterIPSubnet
  1088. //
  1089. // Description:
  1090. //
  1091. // Arguments:
  1092. // bstrSubnetMaskIn
  1093. //
  1094. // Return Values:
  1095. //
  1096. //--
  1097. //////////////////////////////////////////////////////////////////////////////
  1098. STDMETHODIMP
  1099. CClusCfgWizard::put_ClusterIPSubnet(
  1100. BSTR bstrIPSubnetIn
  1101. )
  1102. {
  1103. TraceFunc1( "[IClusCfgWizard] bstrIPSubnetIn = '%ls'", bstrIPSubnetIn );
  1104. HRESULT hr = S_OK;
  1105. DWORD dwStatus;
  1106. if ( bstrIPSubnetIn == NULL )
  1107. {
  1108. hr = THR( E_INVALIDARG );
  1109. goto Cleanup;
  1110. }
  1111. dwStatus = TW32( ClRtlTcpipStringToAddress( bstrIPSubnetIn, &m_ulIPSubnet ) );
  1112. if ( dwStatus != ERROR_SUCCESS )
  1113. {
  1114. hr = HRESULT_FROM_WIN32( dwStatus );
  1115. goto Cleanup;
  1116. }
  1117. Cleanup:
  1118. HRETURN( hr );
  1119. } //*** CClusCfgWizard::put_ClusterIPSubnet
  1120. //////////////////////////////////////////////////////////////////////////////
  1121. //++
  1122. //
  1123. // CClusCfgWizard::get_ClusterIPAddressNetwork
  1124. //
  1125. // Description:
  1126. //
  1127. // Arguments:
  1128. // pbstrNetworkNameOut
  1129. //
  1130. // Return Values:
  1131. //
  1132. //--
  1133. //////////////////////////////////////////////////////////////////////////////
  1134. STDMETHODIMP
  1135. CClusCfgWizard::get_ClusterIPAddressNetwork(
  1136. BSTR * pbstrNetworkNameOut
  1137. )
  1138. {
  1139. TraceFunc( "[IClusCfgWizard]" );
  1140. HRESULT hr = S_OK;
  1141. if ( pbstrNetworkNameOut == NULL )
  1142. {
  1143. hr = THR( E_POINTER );
  1144. goto Cleanup;
  1145. }
  1146. *pbstrNetworkNameOut = NULL;
  1147. if ( m_bstrNetworkName == NULL )
  1148. {
  1149. hr = S_FALSE;
  1150. goto Cleanup;
  1151. }
  1152. *pbstrNetworkNameOut = SysAllocString( m_bstrNetworkName );
  1153. if ( *pbstrNetworkNameOut == NULL )
  1154. {
  1155. hr = THR( E_OUTOFMEMORY );
  1156. goto Cleanup;
  1157. }
  1158. Cleanup:
  1159. HRETURN( hr );
  1160. } //*** CClusCfgWizard::get_ClusterIPAddressNetwork
  1161. //////////////////////////////////////////////////////////////////////////////
  1162. //++
  1163. //
  1164. // CClusCfgWizard::put_ClusterIPAddressNetwork
  1165. //
  1166. // Description:
  1167. //
  1168. // Arguments:
  1169. // bstrNetworkNameIn
  1170. //
  1171. // Return Values:
  1172. //
  1173. //--
  1174. //////////////////////////////////////////////////////////////////////////////
  1175. STDMETHODIMP
  1176. CClusCfgWizard::put_ClusterIPAddressNetwork(
  1177. BSTR bstrNetworkNameIn
  1178. )
  1179. {
  1180. TraceFunc1( "[IClusCfgWizard] bstrNetworkNameIn = '%ls'", bstrNetworkNameIn == NULL ? L"<null>" : bstrNetworkNameIn );
  1181. HRESULT hr = S_OK;
  1182. BSTR bstrNewNetworkName;
  1183. if ( bstrNetworkNameIn == NULL )
  1184. {
  1185. hr = THR( E_INVALIDARG );
  1186. goto Cleanup;
  1187. }
  1188. bstrNewNetworkName = TraceSysAllocString( bstrNetworkNameIn );
  1189. if ( bstrNewNetworkName == NULL )
  1190. {
  1191. hr = THR( E_OUTOFMEMORY );
  1192. goto Cleanup;
  1193. }
  1194. if ( m_bstrNetworkName != NULL )
  1195. {
  1196. TraceSysFreeString( m_bstrNetworkName );
  1197. }
  1198. m_bstrNetworkName = bstrNewNetworkName;
  1199. Cleanup:
  1200. HRETURN( hr );
  1201. } //*** CClusCfgWizard::put_ClusterIPAddressNetwork
  1202. //////////////////////////////////////////////////////////////////////////////
  1203. //++
  1204. //
  1205. // CClusCfgWizard::get_MinimumConfiguration
  1206. //
  1207. // Description:
  1208. //
  1209. // Arguments:
  1210. // pfMinimumConfigurationOut
  1211. //
  1212. // Return Values:
  1213. //
  1214. //--
  1215. //////////////////////////////////////////////////////////////////////////////
  1216. STDMETHODIMP
  1217. CClusCfgWizard::get_MinimumConfiguration(
  1218. BOOL * pfMinimumConfigurationOut
  1219. )
  1220. {
  1221. TraceFunc( "" );
  1222. HRESULT hr = S_OK;
  1223. if ( pfMinimumConfigurationOut == NULL )
  1224. {
  1225. hr = THR( E_POINTER );
  1226. goto Cleanup;
  1227. } // if:
  1228. *pfMinimumConfigurationOut = m_fMinimalConfig;
  1229. Cleanup:
  1230. HRETURN( hr );
  1231. } //*** CClusCfgWizard::get_MinimumConfiguration
  1232. //////////////////////////////////////////////////////////////////////////////
  1233. //++
  1234. //
  1235. // CClusCfgWizard::put_MinimumConfiguration
  1236. //
  1237. // Description:
  1238. //
  1239. // Arguments:
  1240. // fMinimumConfigurationIn
  1241. //
  1242. // Return Values:
  1243. //
  1244. //--
  1245. //////////////////////////////////////////////////////////////////////////////
  1246. STDMETHODIMP
  1247. CClusCfgWizard::put_MinimumConfiguration(
  1248. BOOL fMinimumConfigurationIn
  1249. )
  1250. {
  1251. TraceFunc1( "[IClusCfgWizard] fMinimalConfigurationIn = '%ls'", fMinimumConfigurationIn ? L"TRUE" : L"FALSE" );
  1252. HRESULT hr = S_OK;
  1253. m_fMinimalConfig = fMinimumConfigurationIn;
  1254. HRETURN( hr );
  1255. } //*** CClusCfgWizard::put_MinimumConfiguration
  1256. //////////////////////////////////////////////////////////////////////////////
  1257. //++
  1258. //
  1259. // CClusCfgWizard::AddComputer
  1260. //
  1261. // Description:
  1262. //
  1263. // Arguments:
  1264. // bstrNameIn
  1265. //
  1266. // Return Values:
  1267. //
  1268. //--
  1269. //////////////////////////////////////////////////////////////////////////////
  1270. STDMETHODIMP
  1271. CClusCfgWizard::AddComputer(
  1272. BSTR bstrNameIn
  1273. )
  1274. {
  1275. TraceFunc1( "[IClusCfgWizard] pcszNameIn = '%ls'", bstrNameIn == NULL ? L"<null>" : bstrNameIn );
  1276. HRESULT hr = S_OK;
  1277. if ( bstrNameIn == NULL )
  1278. {
  1279. hr = THR( E_POINTER );
  1280. goto Cleanup;
  1281. }
  1282. hr = THR( HrAddNode( bstrNameIn, true ) );
  1283. if ( FAILED( hr ) )
  1284. {
  1285. goto Cleanup;
  1286. }
  1287. Cleanup:
  1288. HRETURN( hr );
  1289. } //*** CClusCfgWizard::AddComputer
  1290. //////////////////////////////////////////////////////////////////////////////
  1291. //++
  1292. //
  1293. // CClusCfgWizard::RemoveComputer
  1294. //
  1295. // Description:
  1296. //
  1297. // Arguments:
  1298. // pcszNameIn
  1299. //
  1300. // Return Values:
  1301. //
  1302. //--
  1303. //////////////////////////////////////////////////////////////////////////////
  1304. STDMETHODIMP
  1305. CClusCfgWizard::RemoveComputer(
  1306. BSTR bstrNameIn
  1307. )
  1308. {
  1309. TraceFunc1( "[IClusCfgWizard] pcszNameIn = '%ls'", bstrNameIn == NULL ? L"<null>" : bstrNameIn );
  1310. HRESULT hr = S_FALSE;
  1311. NamedCookieArray::Iterator itNode = m_ncaNodes.ItBegin();
  1312. if ( bstrNameIn == NULL )
  1313. {
  1314. hr = THR( E_POINTER );
  1315. goto Cleanup;
  1316. }
  1317. // Look for a node that has the same name.
  1318. while ( ( itNode != m_ncaNodes.ItEnd() ) && ( NBSTRCompareNoCase( ( *itNode ).bstrName, bstrNameIn ) != 0 ) )
  1319. {
  1320. ++itNode;
  1321. }
  1322. // If a node with the same name exists, remove it.
  1323. if ( itNode != m_ncaNodes.ItEnd() )
  1324. {
  1325. if ( ( *itNode ).FHasCookie() )
  1326. {
  1327. THR( m_pom->RemoveObject( ( *itNode ).ocObject ) );
  1328. }
  1329. hr = THR( m_ncaNodes.HrRemove( itNode ) );
  1330. if ( FAILED( hr ) )
  1331. {
  1332. goto Cleanup;
  1333. }
  1334. }
  1335. else // No node has the same name.
  1336. {
  1337. hr = S_FALSE;
  1338. }
  1339. Cleanup:
  1340. HRETURN( hr );
  1341. } //*** CClusCfgWizard::RemoveComputer
  1342. //////////////////////////////////////////////////////////////////////////////
  1343. //++
  1344. //
  1345. // CClusCfgWizard::ClearComputerList
  1346. //
  1347. // Description:
  1348. //
  1349. // Arguments:
  1350. // None.
  1351. //
  1352. // Return Values:
  1353. //
  1354. //--
  1355. //////////////////////////////////////////////////////////////////////////////
  1356. STDMETHODIMP
  1357. CClusCfgWizard::ClearComputerList( void )
  1358. {
  1359. TraceFunc( "[IClusCfgWizard]" );
  1360. HRESULT hr = S_OK;
  1361. hr = THR( HrReleaseNodeObjects() );
  1362. if ( FAILED( hr ) )
  1363. {
  1364. goto Cleanup;
  1365. }
  1366. m_ncaNodes.Clear();
  1367. Cleanup:
  1368. HRETURN( hr );
  1369. } //*** CClusCfgWizard::ClearComputerList
  1370. //****************************************************************************
  1371. //
  1372. // Private
  1373. //
  1374. //****************************************************************************
  1375. //////////////////////////////////////////////////////////////////////////////
  1376. //++
  1377. //
  1378. // CClusCfgWizard::HrAddWizardPage
  1379. //
  1380. // Description:
  1381. // Fills in the PROPSHEETPAGE structure, create the page and adds it to
  1382. // the wizard's PROPSHEETHEADER.
  1383. //
  1384. // Arguments:
  1385. // ppshInout
  1386. // LPPROPSHEETHEADER structure to add page to.
  1387. //
  1388. // idTemplateIn
  1389. // The dialog template ID of the page.
  1390. //
  1391. // pfnDlgProcIn
  1392. // The dialog proc for the page.
  1393. //
  1394. // idCaptionIn
  1395. // The page's caption.
  1396. //
  1397. // idTitleIn
  1398. // The page's title.
  1399. //
  1400. // idSubtitleIn
  1401. // The page's sub-title.
  1402. //
  1403. // lParam
  1404. // The lParam to be put into the PROPSHEETPAGE stucture's lParam.
  1405. //
  1406. // Return Values:
  1407. // S_OK
  1408. // The call succeeded.
  1409. //
  1410. //--
  1411. //////////////////////////////////////////////////////////////////////////////
  1412. HRESULT
  1413. CClusCfgWizard::HrAddWizardPage(
  1414. LPPROPSHEETHEADER ppshInout,
  1415. UINT idTemplateIn,
  1416. DLGPROC pfnDlgProcIn,
  1417. UINT idTitleIn,
  1418. UINT idSubtitleIn,
  1419. LPARAM lParam
  1420. )
  1421. {
  1422. TraceFunc( "" );
  1423. PROPSHEETPAGE psp;
  1424. TCHAR szTitle[ 256 ];
  1425. TCHAR szSubTitle[ 256 ];
  1426. ZeroMemory( &psp, sizeof(psp) );
  1427. psp.dwSize = sizeof(psp);
  1428. psp.dwFlags = PSP_USETITLE;
  1429. psp.pszTitle = ppshInout->pszCaption;
  1430. psp.hInstance = ppshInout->hInstance;
  1431. psp.pszTemplate = MAKEINTRESOURCE( idTemplateIn );
  1432. psp.pfnDlgProc = pfnDlgProcIn;
  1433. psp.lParam = lParam;
  1434. if ( ( idTemplateIn == IDD_WELCOME_CREATE )
  1435. || ( idTemplateIn == IDD_WELCOME_ADD )
  1436. || ( idTemplateIn == IDD_COMPLETION )
  1437. )
  1438. {
  1439. psp.dwFlags |= PSP_HIDEHEADER;
  1440. }
  1441. else
  1442. {
  1443. if ( idTitleIn != 0 )
  1444. {
  1445. DWORD dw;
  1446. dw = LoadString( g_hInstance, idTitleIn, szTitle, ARRAYSIZE(szTitle) );
  1447. Assert( dw );
  1448. psp.pszHeaderTitle = szTitle;
  1449. psp.dwFlags |= PSP_USEHEADERTITLE;
  1450. }
  1451. else
  1452. {
  1453. psp.pszHeaderTitle = NULL;
  1454. }
  1455. if ( idSubtitleIn != 0 )
  1456. {
  1457. DWORD dw;
  1458. dw = LoadString( g_hInstance, idSubtitleIn, szSubTitle, ARRAYSIZE(szSubTitle) );
  1459. Assert( dw );
  1460. psp.pszHeaderSubTitle = szSubTitle;
  1461. psp.dwFlags |= PSP_USEHEADERSUBTITLE;
  1462. }
  1463. else
  1464. {
  1465. psp.pszHeaderSubTitle = NULL;
  1466. }
  1467. }
  1468. ppshInout->phpage[ ppshInout->nPages ] = CreatePropertySheetPage( &psp );
  1469. Assert( ppshInout->phpage[ ppshInout->nPages ] != NULL );
  1470. if ( ppshInout->phpage[ ppshInout->nPages ] != NULL )
  1471. {
  1472. ppshInout->nPages++;
  1473. }
  1474. HRETURN( S_OK );
  1475. } //*** CClusCfgWizard::HrAddWizardPage
  1476. //////////////////////////////////////////////////////////////////////////////
  1477. //++
  1478. //
  1479. // CClusCfgWizard::HrIsCompatibleNodeDomain
  1480. //
  1481. // Description:
  1482. // Determine whether the domain of a node being added to the cluster
  1483. // matches that already established for the cluster.
  1484. //
  1485. // Arguments:
  1486. // pcwszDomainIn - The domain of the proposed node.
  1487. //
  1488. // Return Values:
  1489. // S_OK
  1490. // Either the domain matches, or the cluster is empty.
  1491. //
  1492. // S_FALSE
  1493. // The domain does not match the cluster's.
  1494. //
  1495. //--
  1496. //////////////////////////////////////////////////////////////////////////////
  1497. STDMETHODIMP
  1498. CClusCfgWizard::HrIsCompatibleNodeDomain(
  1499. LPCWSTR pcwszDomainIn
  1500. )
  1501. {
  1502. TraceFunc( "" );
  1503. HRESULT hr = S_OK;
  1504. if ( ( m_bstrClusterDomain != NULL ) && ( ClRtlStrICmp( pcwszDomainIn, m_bstrClusterDomain ) != 0 ) )
  1505. {
  1506. hr = S_FALSE;
  1507. }
  1508. HRETURN( hr );
  1509. } //*** CClusCfgWizard::HrIsCompatibleNodeDomain
  1510. //////////////////////////////////////////////////////////////////////////////
  1511. //++
  1512. //
  1513. // HrLaunchCleanupTask
  1514. //
  1515. // Description:
  1516. // When the wizard has been canceled after analysis has completed
  1517. // the cancel cleanup task needs to be run to ensure that all
  1518. // cleanup has occured.
  1519. //
  1520. // Arguments:
  1521. // None.
  1522. //
  1523. // Return Values:
  1524. // S_OK
  1525. // Success
  1526. //
  1527. // HRESULT errors
  1528. //
  1529. // Remarks:
  1530. //
  1531. //--
  1532. //////////////////////////////////////////////////////////////////////////////
  1533. HRESULT
  1534. CClusCfgWizard::HrLaunchCleanupTask( void )
  1535. {
  1536. TraceFunc( "" );
  1537. Assert( m_cookieCompletion == 0 );
  1538. HRESULT hr = S_OK;
  1539. IUnknown * punk = NULL;
  1540. ITaskCancelCleanup * ptcc = NULL;
  1541. OBJECTCOOKIE cookieCluster;
  1542. ULONG ulCurrent;
  1543. DWORD sc;
  1544. hr = HrGetCompletionCookie( CLSID_CancelCleanupTaskCompletionCookieType, &m_cookieCompletion );
  1545. if ( hr == E_PENDING )
  1546. {
  1547. // no-op.
  1548. } // if:
  1549. else if ( FAILED( hr ) )
  1550. {
  1551. THR( hr );
  1552. goto Cleanup;
  1553. } // else if:
  1554. hr = THR( HrCreateTask( TASK_CancelCleanup, &punk ) );
  1555. if ( FAILED( hr ) )
  1556. {
  1557. goto Cleanup;
  1558. } // if:
  1559. hr = THR( punk->TypeSafeQI( ITaskCancelCleanup, &ptcc ) );
  1560. if ( FAILED( hr ) )
  1561. {
  1562. goto Cleanup;
  1563. } // if:
  1564. hr = THR( HrGetClusterCookie( &cookieCluster ) );
  1565. if ( FAILED( hr ) )
  1566. {
  1567. goto Cleanup;
  1568. } // if:
  1569. hr = THR( ptcc->SetCompletionCookie( m_cookieCompletion ) );
  1570. if ( FAILED( hr ) )
  1571. {
  1572. goto Cleanup;
  1573. } // if:
  1574. hr = THR( HrSubmitTask( ptcc ) );
  1575. if ( FAILED( hr ) )
  1576. {
  1577. goto Cleanup;
  1578. } // if:
  1579. //
  1580. // Wait for task to complete.
  1581. //
  1582. for ( ulCurrent = 0, sc = WAIT_OBJECT_0 + 1
  1583. ; ( sc != WAIT_OBJECT_0 )
  1584. ; ulCurrent++
  1585. )
  1586. {
  1587. MSG msg;
  1588. while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
  1589. {
  1590. TranslateMessage( &msg );
  1591. DispatchMessage( &msg );
  1592. } // while:
  1593. sc = MsgWaitForMultipleObjectsEx(
  1594. 1
  1595. , &m_hCancelCleanupEvent
  1596. , INFINITE
  1597. , QS_ALLEVENTS | QS_ALLINPUT | QS_ALLPOSTMESSAGE
  1598. , 0
  1599. );
  1600. } // while: sc == WAIT_OBJECT_0
  1601. Cleanup:
  1602. if ( m_cookieCompletion != 0 )
  1603. {
  1604. THR( HrReleaseCompletionObject( m_cookieCompletion ) );
  1605. m_cookieCompletion = 0;
  1606. } // if:
  1607. if ( ptcc != NULL )
  1608. {
  1609. ptcc->Release();
  1610. } // if:
  1611. if ( punk != NULL )
  1612. {
  1613. punk->Release();
  1614. } // if:
  1615. HRETURN( hr );
  1616. } //*** CClusCfgWizard::HrLaunchCleanupTask
  1617. //****************************************************************************
  1618. //
  1619. // Non-COM public methods: cluster access
  1620. //
  1621. //****************************************************************************
  1622. //////////////////////////////////////////////////////////////////////////////
  1623. //++
  1624. //
  1625. // CClusCfgWizard::HrSetClusterName
  1626. //
  1627. // Description:
  1628. // Sets the cluster name, overwriting any current name.
  1629. //
  1630. // Arguments:
  1631. // pwcszClusterNameIn - The new cluster name.
  1632. // fAcceptNonRFCCharsIn - Allow the name to contain non-RFC chars.
  1633. //
  1634. // Return Values:
  1635. // S_OK
  1636. // Changing the cluster name succeeded.
  1637. //
  1638. // S_FALSE
  1639. // The cluster already has this name.
  1640. //
  1641. // Other errors
  1642. // Something went wrong, and the cluster's name hasn't changed.
  1643. //
  1644. //--
  1645. //////////////////////////////////////////////////////////////////////////////
  1646. STDMETHODIMP
  1647. CClusCfgWizard::HrSetClusterName(
  1648. LPCWSTR pwcszClusterNameIn
  1649. , bool fAcceptNonRFCCharsIn
  1650. )
  1651. {
  1652. TraceFunc( "" );
  1653. HRESULT hr = S_OK;
  1654. BSTR bstrClusterFQN = NULL;
  1655. BSTR bstrClusterDisplay = NULL;
  1656. BSTR bstrClusterDomain = NULL;
  1657. Assert( pwcszClusterNameIn != NULL );
  1658. if ( pwcszClusterNameIn == NULL )
  1659. {
  1660. hr = THR( E_POINTER );
  1661. goto Cleanup;
  1662. }
  1663. //
  1664. // Determine whether the caller is providing a fully-qualified name,
  1665. // and remember the result, so that the cluster name and domain page knows
  1666. // whether to obtain the domain from the user.
  1667. //
  1668. hr = STHR( HrIsValidFQN( pwcszClusterNameIn, true ) );
  1669. if ( FAILED( hr ) )
  1670. {
  1671. goto Cleanup;
  1672. }
  1673. m_fDefaultedDomain = ( hr == S_FALSE );
  1674. // Make corresponding FQName.
  1675. hr = THR( HrMakeFQN(
  1676. pwcszClusterNameIn
  1677. , NULL // Default to local machine's domain.
  1678. , fAcceptNonRFCCharsIn
  1679. , &bstrClusterFQN
  1680. ) );
  1681. if ( FAILED( hr ) )
  1682. {
  1683. goto Cleanup;
  1684. }
  1685. // Get domain name from FQName.
  1686. {
  1687. size_t idxClusterDomain = 0;
  1688. hr = THR( HrFindDomainInFQN( bstrClusterFQN, &idxClusterDomain ) );
  1689. if ( FAILED( hr ) )
  1690. {
  1691. goto Cleanup;
  1692. }
  1693. bstrClusterDomain = TraceSysAllocString( ( bstrClusterFQN + idxClusterDomain ) );
  1694. if ( bstrClusterDomain == NULL )
  1695. {
  1696. hr = THR( E_OUTOFMEMORY );
  1697. goto Cleanup;
  1698. }
  1699. }
  1700. // If bstrClusterFQN is an FQIP,
  1701. hr = STHR( HrFQNIsFQIP( bstrClusterFQN ) );
  1702. if ( FAILED( hr ) )
  1703. {
  1704. goto Cleanup;
  1705. }
  1706. else if ( hr == S_OK ) // set display name to IP address;
  1707. {
  1708. hr = THR( HrExtractPrefixFromFQN( bstrClusterFQN, &bstrClusterDisplay ) );
  1709. if ( FAILED( hr ) )
  1710. {
  1711. goto Cleanup;
  1712. }
  1713. }
  1714. else // otherwise, set display name to pwcszClusterNameIn.
  1715. {
  1716. hr = S_OK;
  1717. bstrClusterDisplay = TraceSysAllocString( pwcszClusterNameIn );
  1718. if ( bstrClusterDisplay == NULL )
  1719. {
  1720. hr = THR( E_OUTOFMEMORY );
  1721. goto Cleanup;
  1722. }
  1723. }
  1724. // If already have a cluster name,
  1725. if ( FHasClusterName() )
  1726. {
  1727. // if names are equal, bail out with S_FALSE;
  1728. if ( ( NBSTRCompareNoCase( m_ncCluster.bstrName, bstrClusterDisplay ) == 0 )
  1729. && ( NBSTRCompareNoCase( m_bstrClusterDomain, bstrClusterDomain ) == 0 ) )
  1730. {
  1731. hr = S_FALSE;
  1732. goto Cleanup;
  1733. }
  1734. else // otherwise, dump current cluster.
  1735. {
  1736. hr = THR( HrReleaseClusterObject() );
  1737. if ( FAILED( hr ) )
  1738. {
  1739. goto Cleanup;
  1740. }
  1741. m_ncCluster.Erase();
  1742. TraceSysFreeString( m_bstrClusterDomain );
  1743. m_bstrClusterDomain = NULL;
  1744. }
  1745. }
  1746. // Set cluster names.
  1747. m_bstrClusterDomain = bstrClusterDomain;
  1748. bstrClusterDomain = NULL;
  1749. m_ncCluster.bstrName = bstrClusterDisplay;
  1750. bstrClusterDisplay = NULL;
  1751. Cleanup:
  1752. TraceSysFreeString( bstrClusterFQN );
  1753. TraceSysFreeString( bstrClusterDisplay );
  1754. TraceSysFreeString( bstrClusterDomain );
  1755. HRETURN( hr );
  1756. } //*** CClusCfgWizard::HrSetClusterName
  1757. //////////////////////////////////////////////////////////////////////////////
  1758. //++
  1759. //
  1760. // CClusCfgWizard::HrGetClusterDomain
  1761. //
  1762. // Description:
  1763. // Retrieve the cluster's domain.
  1764. //
  1765. // Arguments:
  1766. // pbstrDomainOut - The cluster's domain.
  1767. //
  1768. // Return Values:
  1769. // S_OK
  1770. // *pbstrDomainOut is a BSTR containing the cluster's domain; the
  1771. // caller needs to free it with TraceSysFreeString.
  1772. //
  1773. // S_FALSE
  1774. // Same as S_OK, except that the cluster's domain was not specified
  1775. // by the caller who set it, and so it defaulted to the local machine's.
  1776. //
  1777. // E_POINTER
  1778. // pbstrDomainOut was null.
  1779. //
  1780. // HRESULT_FROM_WIN32( ERROR_INVALID_DOMAINNAME )
  1781. // The cluster's name and domain are not yet defined.
  1782. //
  1783. // Other failures are possible.
  1784. //
  1785. //--
  1786. //////////////////////////////////////////////////////////////////////////////
  1787. STDMETHODIMP
  1788. CClusCfgWizard::HrGetClusterDomain(
  1789. BSTR* pbstrDomainOut
  1790. )
  1791. {
  1792. TraceFunc( "" );
  1793. HRESULT hr = S_OK;
  1794. Assert( pbstrDomainOut != NULL );
  1795. if ( pbstrDomainOut == NULL )
  1796. {
  1797. hr = THR( E_POINTER );
  1798. goto Cleanup;
  1799. }
  1800. *pbstrDomainOut = NULL;
  1801. if ( !FHasClusterName() )
  1802. {
  1803. hr = HRESULT_FROM_WIN32( TW32( ERROR_INVALID_DOMAINNAME ) );
  1804. goto Cleanup;
  1805. }
  1806. *pbstrDomainOut = TraceSysAllocString( m_bstrClusterDomain );
  1807. if ( *pbstrDomainOut == NULL )
  1808. {
  1809. hr = THR( E_OUTOFMEMORY );
  1810. goto Cleanup;
  1811. }
  1812. hr = ( m_fDefaultedDomain? S_FALSE: S_OK );
  1813. Cleanup:
  1814. HRETURN( hr );
  1815. } //*** CClusCfgWizard::HrGetClusterDomain
  1816. //////////////////////////////////////////////////////////////////////////////
  1817. //++
  1818. //
  1819. // CClusCfgWizard::HrGetClusterObject
  1820. //
  1821. // Description:
  1822. // Retrieve the CClusCfgServer object representing the cluster,
  1823. // creating it if necessary.
  1824. //
  1825. // Arguments:
  1826. // ppClusterOut
  1827. // A pointer to the CClusCfgServer object; can be null if the
  1828. // caller wants just to ensure the object exists.
  1829. //
  1830. // Return Values:
  1831. // S_OK
  1832. // The cluster object exists; if ppClusterOut is not null,
  1833. // *ppClusterOut points to the object and the caller must
  1834. // release it.
  1835. //
  1836. // E_PENDING
  1837. // The cluster object has not been initialized,
  1838. // and *ppClusterOut is null.
  1839. //
  1840. // HRESULT_FROM_WIN32( ERROR_INVALID_ACCOUNT_NAME )
  1841. // The cluster's name has not yet been set.
  1842. //
  1843. // Other failures are possible.
  1844. //
  1845. //--
  1846. //////////////////////////////////////////////////////////////////////////////
  1847. STDMETHODIMP
  1848. CClusCfgWizard::HrGetClusterObject(
  1849. IClusCfgClusterInfo ** ppClusterOut
  1850. )
  1851. {
  1852. TraceFunc( "" );
  1853. HRESULT hr = S_OK;
  1854. if ( ppClusterOut != NULL )
  1855. {
  1856. *ppClusterOut = NULL;
  1857. }
  1858. if ( !m_ncCluster.FHasObject() )
  1859. {
  1860. if ( !m_ncCluster.FHasCookie() )
  1861. {
  1862. hr = STHR( HrGetClusterCookie( NULL ) );
  1863. if ( FAILED( hr ) )
  1864. {
  1865. goto Cleanup;
  1866. }
  1867. }
  1868. hr = THR( m_pom->GetObject( DFGUID_ClusterConfigurationInfo, m_ncCluster.ocObject, &m_ncCluster.punkObject ) );
  1869. if ( FAILED( hr ) )
  1870. {
  1871. goto Cleanup;
  1872. }
  1873. } // m_ncCluster currently has no object pointer.
  1874. if ( ppClusterOut != NULL )
  1875. {
  1876. hr = THR( m_ncCluster.punkObject->QueryInterface( IID_IClusCfgClusterInfo, reinterpret_cast< void ** >( ppClusterOut ) ) );
  1877. if ( FAILED( hr ) )
  1878. {
  1879. goto Cleanup;
  1880. }
  1881. }
  1882. Cleanup:
  1883. HRETURN( hr );
  1884. } //*** CClusCfgWizard::HrGetClusterObject
  1885. //////////////////////////////////////////////////////////////////////////////
  1886. //++
  1887. //
  1888. // CClusCfgWizard::HrGetClusterCookie
  1889. //
  1890. // Description:
  1891. // Retrieve the ObjectManager cookie corresponding to the cluster,
  1892. // creating it if necessary.
  1893. //
  1894. // Arguments:
  1895. // pocClusterOut
  1896. // A pointer to the ObjectManager cookie; can be null if the
  1897. // caller wants just to ensure the cookie exists.
  1898. //
  1899. // Return Values:
  1900. // S_OK
  1901. // The cookie exists; if pocClusterOut is not null,
  1902. // *pocClusterOut holds the value of the cookie.
  1903. //
  1904. // S_FALSE
  1905. // Same as S_OK except that the corresponding object is known not
  1906. // to be initialized.
  1907. //
  1908. // HRESULT_FROM_WIN32( ERROR_INVALID_ACCOUNT_NAME )
  1909. // The cluster's name has not yet been set.
  1910. //
  1911. // Other failures are possible.
  1912. //
  1913. //--
  1914. //////////////////////////////////////////////////////////////////////////////
  1915. STDMETHODIMP
  1916. CClusCfgWizard::HrGetClusterCookie(
  1917. OBJECTCOOKIE * pocClusterOut
  1918. )
  1919. {
  1920. TraceFunc( "" );
  1921. HRESULT hr = S_OK;
  1922. BSTR bstrClusterFQN = NULL;
  1923. // Clear *pocClusterOut in case of failure.
  1924. if ( pocClusterOut != NULL )
  1925. {
  1926. *pocClusterOut = 0;
  1927. }
  1928. Assert( FHasClusterName() );
  1929. if ( !FHasClusterName() )
  1930. {
  1931. hr = HRESULT_FROM_WIN32( TW32( ERROR_INVALID_ACCOUNT_NAME ) );
  1932. goto Cleanup;
  1933. }
  1934. // Get the cookie from the object manager if necessary.
  1935. if ( !m_ncCluster.FHasCookie() )
  1936. {
  1937. // Make FQName for cluster.
  1938. hr = THR( HrMakeFQN( m_ncCluster.bstrName, m_bstrClusterDomain, true, &bstrClusterFQN ) );
  1939. if ( FAILED( hr ) )
  1940. {
  1941. goto Cleanup;
  1942. }
  1943. hr = m_pom->FindObject(
  1944. CLSID_ClusterConfigurationType
  1945. , 0
  1946. , bstrClusterFQN
  1947. , DFGUID_ClusterConfigurationInfo
  1948. , &m_ncCluster.ocObject
  1949. , &m_ncCluster.punkObject
  1950. );
  1951. if ( hr == E_PENDING )
  1952. {
  1953. hr = S_FALSE;
  1954. }
  1955. else if ( FAILED( hr ) )
  1956. {
  1957. THR( hr );
  1958. goto Cleanup;
  1959. }
  1960. } // m_ncCluster currently has no cookie.
  1961. // Set the cookie if the caller wants it.
  1962. if ( pocClusterOut != NULL )
  1963. {
  1964. *pocClusterOut = m_ncCluster.ocObject;
  1965. }
  1966. Cleanup:
  1967. TraceSysFreeString( bstrClusterFQN );
  1968. HRETURN( hr );
  1969. } //*** CClusCfgWizard::HrGetClusterCookie
  1970. //////////////////////////////////////////////////////////////////////////////
  1971. //++
  1972. //
  1973. // CClusCfgWizard::HrGetClusterChild
  1974. //
  1975. // Description:
  1976. // Retrieve an object which the ObjectManager regards as a child of
  1977. // the cluster.
  1978. //
  1979. // Arguments:
  1980. // rclsidChildIn - The child's class.
  1981. // rguidFormatIn - The child's "data format."
  1982. // ppunkChildOut - A pointer to the child object.
  1983. //
  1984. // Return Values:
  1985. // S_OK
  1986. // The call succeeded and *ppunkChildOut points to a valid object,
  1987. // which the caller must release.
  1988. //
  1989. // Failure
  1990. // *ppunkChildOut is null.
  1991. //
  1992. //--
  1993. //////////////////////////////////////////////////////////////////////////////
  1994. STDMETHODIMP
  1995. CClusCfgWizard::HrGetClusterChild(
  1996. REFCLSID rclsidChildIn
  1997. , REFGUID rguidFormatIn
  1998. , IUnknown ** ppunkChildOut
  1999. )
  2000. {
  2001. TraceFunc( "" );
  2002. HRESULT hr = S_OK;
  2003. OBJECTCOOKIE ocChild = 0;
  2004. Assert( ppunkChildOut != NULL );
  2005. if ( ppunkChildOut == NULL )
  2006. {
  2007. hr = THR( E_POINTER );
  2008. goto Cleanup;
  2009. }
  2010. *ppunkChildOut = NULL;
  2011. if ( !m_ncCluster.FHasCookie() )
  2012. {
  2013. hr = STHR( HrGetClusterCookie( NULL ) );
  2014. if ( FAILED( hr ) )
  2015. {
  2016. goto Cleanup;
  2017. }
  2018. }
  2019. hr = THR( m_pom->FindObject(
  2020. rclsidChildIn
  2021. , m_ncCluster.ocObject
  2022. , NULL
  2023. , rguidFormatIn
  2024. , &ocChild
  2025. , ppunkChildOut
  2026. ) );
  2027. if ( FAILED( hr ) )
  2028. {
  2029. goto Cleanup;
  2030. }
  2031. Cleanup:
  2032. HRETURN( hr );
  2033. } //*** CClusCfgWizard::HrGetClusterChild
  2034. //////////////////////////////////////////////////////////////////////////////
  2035. //++
  2036. //
  2037. // CClusCfgWizard::HrReleaseClusterObject
  2038. //
  2039. // Description:
  2040. // Discard the cluster object (if one exists) and all nodes, and
  2041. // ask the object manager to do the same, but preserve the cluster's
  2042. // name (as well as the node names).
  2043. //
  2044. // Arguments:
  2045. // None.
  2046. //
  2047. // Return Values:
  2048. // S_OK
  2049. // Failure
  2050. //
  2051. //--
  2052. //////////////////////////////////////////////////////////////////////////////
  2053. STDMETHODIMP
  2054. CClusCfgWizard::HrReleaseClusterObject( void )
  2055. {
  2056. TraceFunc( "" );
  2057. HRESULT hr = S_OK;
  2058. if ( m_ncCluster.FHasCookie() )
  2059. {
  2060. hr = THR( HrReleaseNodeObjects() );
  2061. if ( FAILED( hr ) )
  2062. {
  2063. goto Cleanup;
  2064. }
  2065. hr = THR( m_pom->RemoveObject( m_ncCluster.ocObject ) );
  2066. if ( FAILED( hr ) )
  2067. {
  2068. goto Cleanup;
  2069. }
  2070. m_ncCluster.ocObject = 0;
  2071. m_ncCluster.ReleaseObject();
  2072. } // If: cluster cookie exists.
  2073. Cleanup:
  2074. HRETURN( hr );
  2075. } //*** CClusCfgWizard::HrReleaseClusterObject
  2076. //****************************************************************************
  2077. //
  2078. // Non-COM public methods: node access
  2079. //
  2080. //****************************************************************************
  2081. //////////////////////////////////////////////////////////////////////////////
  2082. //++
  2083. //
  2084. // CClusCfgWizard::HrAddNode
  2085. //
  2086. // Description:
  2087. // Add a node for the wizard to include in its action.
  2088. //
  2089. // Arguments:
  2090. // pwcszNodeNameIn
  2091. // The node's name; can be anything accepted as the first
  2092. // argument to HrMakeFQN.
  2093. //
  2094. // fAcceptNonRFCCharsIn
  2095. // Allow the node name to contain non-RFC characters.
  2096. //
  2097. // Return Values:
  2098. // S_OK
  2099. // The name is valid and the corresponding machine will be
  2100. // included in the wizard's action.
  2101. //
  2102. // S_FALSE
  2103. // The node is already in the wizard's list.
  2104. //
  2105. // HRESULT_FROM_WIN32( ERROR_CURRENT_DOMAIN_NOT_ALLOWED )
  2106. // The node's domain conflicts either with the cluster's or with
  2107. // that of other nodes in the cluster.
  2108. //
  2109. // Other failures
  2110. //
  2111. //--
  2112. //////////////////////////////////////////////////////////////////////////////
  2113. STDMETHODIMP
  2114. CClusCfgWizard::HrAddNode(
  2115. LPCWSTR pwcszNodeNameIn
  2116. , bool fAcceptNonRFCCharsIn
  2117. )
  2118. {
  2119. TraceFunc( "" );
  2120. HRESULT hr = S_OK;
  2121. BSTR bstrNodeFQN = NULL;
  2122. BSTR bstrNodeDisplay = NULL;
  2123. NamedCookieArray::Iterator it = m_ncaNodes.ItBegin();
  2124. Assert( pwcszNodeNameIn != NULL );
  2125. if ( pwcszNodeNameIn == NULL )
  2126. {
  2127. hr = THR( E_POINTER );
  2128. goto Cleanup;
  2129. }
  2130. // Make corresponding FQName, using cluster domain (or local machine's) as default.
  2131. hr = THR( HrMakeFQN( pwcszNodeNameIn, m_bstrClusterDomain, fAcceptNonRFCCharsIn, &bstrNodeFQN ) );
  2132. if ( FAILED( hr ) )
  2133. {
  2134. goto Cleanup;
  2135. }
  2136. // If bstrNodeFQN is an FQIP,
  2137. hr = STHR( HrFQNIsFQIP( bstrNodeFQN ) );
  2138. if ( FAILED( hr ) )
  2139. {
  2140. goto Cleanup;
  2141. }
  2142. else if ( hr == S_OK ) // set display name to IP address;
  2143. {
  2144. hr = THR( HrExtractPrefixFromFQN( bstrNodeFQN, &bstrNodeDisplay ) );
  2145. if ( FAILED( hr ) )
  2146. {
  2147. goto Cleanup;
  2148. }
  2149. }
  2150. else // otherwise, set display name to pwcszNodeNameIn.
  2151. {
  2152. bstrNodeDisplay = TraceSysAllocString( pwcszNodeNameIn );
  2153. if ( bstrNodeDisplay == NULL )
  2154. {
  2155. hr = THR( E_OUTOFMEMORY );
  2156. goto Cleanup;
  2157. }
  2158. }
  2159. // If name already exists, bail out with S_FALSE;
  2160. while ( it != m_ncaNodes.ItEnd() )
  2161. {
  2162. if ( NBSTRCompareNoCase( ( *it ).bstrName, bstrNodeDisplay ) == 0 )
  2163. {
  2164. hr = S_FALSE;
  2165. goto Cleanup;
  2166. }
  2167. ++it;
  2168. } // For each node currently in the list.
  2169. // Add to node list.
  2170. {
  2171. SNamedCookie ncNewNode;
  2172. ncNewNode.bstrName = bstrNodeDisplay;
  2173. bstrNodeDisplay = NULL;
  2174. hr = THR( m_ncaNodes.HrPushBack( ncNewNode ) );
  2175. if ( FAILED( hr ) )
  2176. {
  2177. goto Cleanup;
  2178. }
  2179. }
  2180. Cleanup:
  2181. TraceSysFreeString( bstrNodeFQN );
  2182. TraceSysFreeString( bstrNodeDisplay );
  2183. HRETURN( hr );
  2184. } //*** CClusCfgWizard::HrAddNode
  2185. //////////////////////////////////////////////////////////////////////////////
  2186. //++
  2187. //
  2188. // CClusCfgWizard::HrGetNodeCount
  2189. //
  2190. // Description:
  2191. // Retrieve the number of nodes currently in the wizard's list.
  2192. //
  2193. // Arguments:
  2194. // pcNodesOut - The node count.
  2195. //
  2196. // Return Values:
  2197. // S_OK
  2198. //
  2199. //--
  2200. //////////////////////////////////////////////////////////////////////////////
  2201. STDMETHODIMP
  2202. CClusCfgWizard::HrGetNodeCount(
  2203. size_t* pcNodesOut
  2204. )
  2205. {
  2206. TraceFunc( "" );
  2207. HRESULT hr = S_OK;
  2208. Assert( pcNodesOut != NULL );
  2209. if ( pcNodesOut == NULL )
  2210. {
  2211. hr = THR( E_POINTER );
  2212. goto Cleanup;
  2213. }
  2214. *pcNodesOut = m_ncaNodes.Count();
  2215. Cleanup:
  2216. HRETURN( hr );
  2217. } //*** CClusCfgWizard::HrGetNodeCount
  2218. //////////////////////////////////////////////////////////////////////////////
  2219. //++
  2220. //
  2221. // CClusCfgWizard::HrGetNodeObject
  2222. //
  2223. // Description:
  2224. // Retrieve the CClusCfgServer object representing a node in the
  2225. // list, creating it if necessary.
  2226. //
  2227. // Arguments:
  2228. // idxNodeIn
  2229. // The zero-based index of the node in the list.
  2230. //
  2231. // ppNodeOut
  2232. // A pointer to the CClusCfgServer object; can be null if the
  2233. // caller wants just to ensure the object exists.
  2234. //
  2235. // Return Values:
  2236. // S_OK
  2237. // The node object exists; if ppNodeOut is not null,
  2238. // *ppNodeOut points to the object and the caller must
  2239. // release it.
  2240. //
  2241. // E_PENDING
  2242. // The node object has not been initialized,
  2243. // and *ppNodeOut is null.
  2244. //
  2245. // Other failures are possible.
  2246. //
  2247. //--
  2248. //////////////////////////////////////////////////////////////////////////////
  2249. STDMETHODIMP
  2250. CClusCfgWizard::HrGetNodeObject(
  2251. size_t idxNodeIn
  2252. , IClusCfgNodeInfo ** ppNodeOut
  2253. )
  2254. {
  2255. TraceFunc( "" );
  2256. HRESULT hr = S_OK;
  2257. // Clear *ppNodeOut in case of failure.
  2258. if ( ppNodeOut != NULL )
  2259. {
  2260. *ppNodeOut = NULL;
  2261. }
  2262. // Make sure index is within bounds.
  2263. Assert( idxNodeIn < m_ncaNodes.Count() );
  2264. if ( idxNodeIn >= m_ncaNodes.Count() )
  2265. {
  2266. hr = THR( E_INVALIDARG );
  2267. goto Cleanup;
  2268. }
  2269. // Obtain the object from the object manager if necessary.
  2270. if ( !m_ncaNodes[ idxNodeIn ].FHasObject() )
  2271. {
  2272. hr = STHR( HrGetNodeCookie( idxNodeIn, NULL ) );
  2273. if ( FAILED( hr ) )
  2274. {
  2275. goto Cleanup;
  2276. }
  2277. hr = THR( m_pom->GetObject(
  2278. DFGUID_NodeInformation
  2279. , m_ncaNodes[ idxNodeIn ].ocObject
  2280. , &m_ncaNodes[ idxNodeIn ].punkObject
  2281. ) );
  2282. if ( FAILED( hr ) )
  2283. {
  2284. goto Cleanup;
  2285. }
  2286. } // If: need to obtain object from object manager.
  2287. // QI for the interface if the caller wants it.
  2288. if ( ppNodeOut != NULL )
  2289. {
  2290. hr = THR( m_ncaNodes[ idxNodeIn ].punkObject->QueryInterface(
  2291. IID_IClusCfgNodeInfo
  2292. , reinterpret_cast< void** >( ppNodeOut )
  2293. ) );
  2294. if ( FAILED( hr ) )
  2295. {
  2296. goto Cleanup;
  2297. }
  2298. }
  2299. Cleanup:
  2300. HRETURN( hr );
  2301. } //*** CClusCfgWizard::HrGetNodeObject
  2302. //////////////////////////////////////////////////////////////////////////////
  2303. //++
  2304. //
  2305. // CClusCfgWizard::HrGetNodeCookie
  2306. //
  2307. // Description:
  2308. // Retrieve the ObjectManager cookie corresponding to the node,
  2309. // creating it if necessary.
  2310. //
  2311. // Arguments:
  2312. // idxNodeIn
  2313. // The zero-based index of the node in the list.
  2314. //
  2315. // pocNodeOut
  2316. // A pointer to the ObjectManager cookie; can be null if the
  2317. // caller wants just to ensure the cookie exists.
  2318. //
  2319. // Return Values:
  2320. // S_OK
  2321. // The cookie exists; if pocNodeOut is not null,
  2322. // *pocNodeOut holds the value of the cookie.
  2323. //
  2324. // S_FALSE
  2325. // Same as S_OK except that the corresponding object is known not
  2326. // to be initialized.
  2327. //
  2328. // Other failures are possible.
  2329. //
  2330. //--
  2331. //////////////////////////////////////////////////////////////////////////////
  2332. STDMETHODIMP
  2333. CClusCfgWizard::HrGetNodeCookie(
  2334. size_t idxNodeIn
  2335. , OBJECTCOOKIE * pocNodeOut
  2336. )
  2337. {
  2338. TraceFunc( "" );
  2339. HRESULT hr = S_OK;
  2340. BSTR bstrNodeFQN = NULL;
  2341. // Clear *pocNodeOut in case of failure.
  2342. if ( pocNodeOut != NULL )
  2343. {
  2344. *pocNodeOut = 0;
  2345. }
  2346. // Make sure index is within bounds.
  2347. Assert( idxNodeIn < m_ncaNodes.Count() );
  2348. if ( idxNodeIn >= m_ncaNodes.Count() )
  2349. {
  2350. hr = THR( E_INVALIDARG );
  2351. goto Cleanup;
  2352. }
  2353. // Get the cookie from the object manager if necessary.
  2354. if ( !m_ncaNodes[ idxNodeIn ].FHasCookie() )
  2355. {
  2356. hr = STHR( HrGetClusterCookie( NULL ) );
  2357. if ( FAILED( hr ) )
  2358. {
  2359. goto Cleanup;
  2360. }
  2361. hr = THR( HrMakeFQN( m_ncaNodes[ idxNodeIn ].bstrName, m_bstrClusterDomain, true, &bstrNodeFQN ) );
  2362. if ( FAILED( hr ) )
  2363. {
  2364. goto Cleanup;
  2365. }
  2366. hr = m_pom->FindObject(
  2367. CLSID_NodeType
  2368. , m_ncCluster.ocObject
  2369. , bstrNodeFQN
  2370. , DFGUID_NodeInformation
  2371. , &m_ncaNodes[ idxNodeIn ].ocObject
  2372. , &m_ncaNodes[ idxNodeIn ].punkObject
  2373. );
  2374. if ( hr == E_PENDING )
  2375. {
  2376. hr = S_FALSE;
  2377. }
  2378. else if ( FAILED( hr ) )
  2379. {
  2380. THR( hr );
  2381. goto Cleanup;
  2382. }
  2383. } // If: node doesn't already have a cookie.
  2384. // Set the cookie if the caller wants it.
  2385. if ( pocNodeOut != NULL )
  2386. {
  2387. *pocNodeOut = m_ncaNodes[ idxNodeIn ].ocObject;
  2388. }
  2389. Cleanup:
  2390. TraceSysFreeString( bstrNodeFQN );
  2391. HRETURN( hr );
  2392. } //*** CClusCfgWizard::HrGetNodeCookie
  2393. //////////////////////////////////////////////////////////////////////////////
  2394. //++
  2395. //
  2396. // CClusCfgWizard::HrGetNodeName
  2397. //
  2398. // Description:
  2399. // Retrieve the node's name.
  2400. //
  2401. // Arguments:
  2402. // idxNodeIn - The zero-based index of the node in the list.
  2403. // pbstrNodeNameOut - The node's name.
  2404. //
  2405. // Return Values:
  2406. // S_OK
  2407. // *pbstrNodeNameOut is a BSTR containing the node's name; the
  2408. // caller needs to free it with TraceSysFreeString.
  2409. //
  2410. // E_POINTER
  2411. // pbstrNodeNameOut was null.
  2412. //
  2413. // E_INVALIDARG
  2414. // The index was out of range for the current set of nodes.
  2415. //
  2416. // Other failures are possible.
  2417. //
  2418. //--
  2419. //////////////////////////////////////////////////////////////////////////////
  2420. STDMETHODIMP
  2421. CClusCfgWizard::HrGetNodeName(
  2422. size_t idxNodeIn
  2423. , BSTR * pbstrNodeNameOut
  2424. )
  2425. {
  2426. TraceFunc( "" );
  2427. HRESULT hr = S_OK;
  2428. // Check out-parameter and set to null in case of failure.
  2429. Assert( pbstrNodeNameOut != NULL );
  2430. if ( pbstrNodeNameOut == NULL )
  2431. {
  2432. hr = THR( E_POINTER );
  2433. goto Cleanup;
  2434. }
  2435. *pbstrNodeNameOut = NULL;
  2436. // Make sure index is within bounds.
  2437. Assert( idxNodeIn < m_ncaNodes.Count() );
  2438. if ( idxNodeIn >= m_ncaNodes.Count() )
  2439. {
  2440. hr = THR( E_INVALIDARG );
  2441. goto Cleanup;
  2442. }
  2443. *pbstrNodeNameOut = TraceSysAllocString( m_ncaNodes[ idxNodeIn ].bstrName );
  2444. if ( *pbstrNodeNameOut == NULL )
  2445. {
  2446. hr = THR( E_OUTOFMEMORY );
  2447. goto Cleanup;
  2448. }
  2449. Cleanup:
  2450. HRETURN( hr );
  2451. } //*** CClusCfgWizard::HrGetNodeName
  2452. //////////////////////////////////////////////////////////////////////////////
  2453. //++
  2454. //
  2455. // CClusCfgWizard::HrGetNodeChild
  2456. //
  2457. // Description:
  2458. // Retrieve an object which the ObjectManager regards as a child of
  2459. // the node.
  2460. //
  2461. // Arguments:
  2462. // idxNodeIn - The zero-based index of the node in the list.
  2463. // rclsidChildIn - The child's class.
  2464. // rguidFormatIn - The child's "data format."
  2465. // ppunkChildOut - A pointer to the child object.
  2466. //
  2467. // Return Values:
  2468. // S_OK
  2469. // The call succeeded and *ppunkChildOut points to a valid object,
  2470. // which the caller must release.
  2471. //
  2472. // Failure
  2473. // *ppunkChildOut is null.
  2474. //
  2475. //--
  2476. //////////////////////////////////////////////////////////////////////////////
  2477. STDMETHODIMP
  2478. CClusCfgWizard::HrGetNodeChild(
  2479. size_t idxNodeIn
  2480. , REFCLSID rclsidChildIn
  2481. , REFGUID rguidFormatIn
  2482. , IUnknown ** ppunkChildOut
  2483. )
  2484. {
  2485. TraceFunc( "" );
  2486. HRESULT hr = S_OK;
  2487. OBJECTCOOKIE ocChild = 0;
  2488. // Check out-parameter and set to null in case of failure.
  2489. Assert( ppunkChildOut != NULL );
  2490. if ( ppunkChildOut == NULL )
  2491. {
  2492. hr = THR( E_POINTER );
  2493. goto Cleanup;
  2494. }
  2495. *ppunkChildOut = NULL;
  2496. // Make sure index is within bounds.
  2497. Assert( idxNodeIn < m_ncaNodes.Count() );
  2498. if ( idxNodeIn >= m_ncaNodes.Count() )
  2499. {
  2500. hr = THR( E_INVALIDARG );
  2501. goto Cleanup;
  2502. }
  2503. // Get the node's cookie if necessary.
  2504. if ( !m_ncaNodes[ idxNodeIn ].FHasCookie() )
  2505. {
  2506. hr = STHR( HrGetNodeCookie( idxNodeIn, NULL ) );
  2507. if ( FAILED( hr ) )
  2508. {
  2509. goto Cleanup;
  2510. }
  2511. }
  2512. // Ask the object manager for the child object.
  2513. hr = THR( m_pom->FindObject(
  2514. rclsidChildIn
  2515. , m_ncaNodes[ idxNodeIn ].ocObject
  2516. , NULL
  2517. , rguidFormatIn
  2518. , &ocChild
  2519. , ppunkChildOut
  2520. ) );
  2521. if ( FAILED( hr ) )
  2522. {
  2523. goto Cleanup;
  2524. }
  2525. Cleanup:
  2526. HRETURN( hr );
  2527. } //*** CClusCfgWizard::HrGetNodeChild
  2528. //////////////////////////////////////////////////////////////////////////////
  2529. //++
  2530. //
  2531. // CClusCfgWizard::HrReleaseNodeObjects
  2532. //
  2533. // Description:
  2534. // Discard all node objects, and ask the object manager to do
  2535. // the same, but preserve the list of names.
  2536. //
  2537. // Arguments:
  2538. // None.
  2539. //
  2540. // Return Values:
  2541. // S_OK
  2542. // Failure
  2543. //
  2544. //--
  2545. //////////////////////////////////////////////////////////////////////////////
  2546. STDMETHODIMP
  2547. CClusCfgWizard::HrReleaseNodeObjects( void )
  2548. {
  2549. TraceFunc( "" );
  2550. HRESULT hr = S_OK;
  2551. for ( NamedCookieArray::Iterator it = m_ncaNodes.ItBegin(); it != m_ncaNodes.ItEnd(); ++it)
  2552. {
  2553. if ( ( *it ).FHasCookie() )
  2554. {
  2555. hr = THR( m_pom->RemoveObject( ( *it ).ocObject ) );
  2556. if ( FAILED( hr ) )
  2557. {
  2558. goto Cleanup;
  2559. }
  2560. ( *it ).ocObject = 0;
  2561. ( *it ).ReleaseObject();
  2562. }
  2563. } // For each node in the list.
  2564. Cleanup:
  2565. HRETURN( hr );
  2566. } //*** CClusCfgWizard::HrReleaseNodeObjects
  2567. //****************************************************************************
  2568. //
  2569. // Non-COM public methods: task access
  2570. //
  2571. //****************************************************************************
  2572. //////////////////////////////////////////////////////////////////////////////
  2573. //++
  2574. //
  2575. // CClusCfgWizard::HrCreateTask
  2576. //
  2577. // Description:
  2578. // Get a new task from the task manager.
  2579. //
  2580. // Arguments:
  2581. // rguidTaskIn - The type of task.
  2582. // ppunkOut - A pointer to the new task.
  2583. //
  2584. // Return Values:
  2585. // S_OK
  2586. // Failure
  2587. //
  2588. //--
  2589. //////////////////////////////////////////////////////////////////////////////
  2590. STDMETHODIMP
  2591. CClusCfgWizard::HrCreateTask(
  2592. REFGUID rguidTaskIn
  2593. , IUnknown ** ppunkOut
  2594. )
  2595. {
  2596. TraceFunc( "" );
  2597. HRESULT hr = S_OK;
  2598. hr = THR( m_ptm->CreateTask( rguidTaskIn, ppunkOut ) );
  2599. if ( FAILED( hr ) )
  2600. {
  2601. goto Cleanup;
  2602. }
  2603. Cleanup:
  2604. HRETURN( hr );
  2605. } //*** CClusCfgWizard::HrCreateTask
  2606. //////////////////////////////////////////////////////////////////////////////
  2607. //++
  2608. //
  2609. // CClusCfgWizard::HrSubmitTask
  2610. //
  2611. // Description:
  2612. // Submit a task to the task manager.
  2613. //
  2614. // Arguments:
  2615. // pTaskIn - A pointer to the task to submit.
  2616. //
  2617. // Return Values:
  2618. // S_OK
  2619. // Failure
  2620. //
  2621. //--
  2622. //////////////////////////////////////////////////////////////////////////////
  2623. STDMETHODIMP
  2624. CClusCfgWizard::HrSubmitTask(
  2625. IDoTask * pTaskIn
  2626. )
  2627. {
  2628. TraceFunc( "" );
  2629. HRESULT hr = S_OK;
  2630. hr = THR( m_ptm->SubmitTask( pTaskIn ) );
  2631. if ( FAILED( hr ) )
  2632. {
  2633. goto Cleanup;
  2634. }
  2635. Cleanup:
  2636. HRETURN( hr );
  2637. } //*** CClusCfgWizard::HrSubmitTask
  2638. //****************************************************************************
  2639. //
  2640. // Non-COM public methods: completion task access
  2641. //
  2642. //****************************************************************************
  2643. //////////////////////////////////////////////////////////////////////////////
  2644. //++
  2645. //
  2646. // CClusCfgWizard::HrGetCompletionCookie
  2647. //
  2648. // Description:
  2649. // Get an object manager cookie for referring to a completion task.
  2650. //
  2651. // Arguments:
  2652. // rguidTaskIn - The type of completion task.
  2653. // pocTaskOut - The task's cookie.
  2654. //
  2655. // Return Values:
  2656. // S_OK
  2657. // E_PENDING - An expected value; the task is not yet complete.
  2658. // Other failures.
  2659. //
  2660. //--
  2661. //////////////////////////////////////////////////////////////////////////////
  2662. STDMETHODIMP
  2663. CClusCfgWizard::HrGetCompletionCookie(
  2664. REFGUID rguidTaskIn
  2665. , OBJECTCOOKIE * pocTaskOut
  2666. )
  2667. {
  2668. TraceFunc( "" );
  2669. HRESULT hr = S_OK;
  2670. IUnknown* punk = NULL;
  2671. hr = m_pom->FindObject(
  2672. rguidTaskIn
  2673. , NULL
  2674. , m_ncCluster.bstrName
  2675. , IID_NULL
  2676. , pocTaskOut
  2677. , &punk // dummy
  2678. );
  2679. if ( FAILED( hr ) && ( hr != E_PENDING ) )
  2680. {
  2681. THR( hr );
  2682. goto Cleanup;
  2683. }
  2684. Cleanup:
  2685. if ( punk != NULL )
  2686. {
  2687. punk->Release();
  2688. }
  2689. HRETURN( hr );
  2690. } //*** CClusCfgWizard::HrGetCompletionCookie
  2691. //////////////////////////////////////////////////////////////////////////////
  2692. //++
  2693. //
  2694. // CClusCfgWizard::HrGetCompletionStatus
  2695. //
  2696. // Description:
  2697. // Get the status of a completion task.
  2698. //
  2699. // Arguments:
  2700. // ocTaskIn
  2701. // The task's cookie, obtained from HrGetCompletionCookie.
  2702. //
  2703. // phrStatusOut
  2704. // The task's current status.
  2705. //
  2706. // Return Values:
  2707. // S_OK
  2708. // Failure
  2709. //
  2710. //--
  2711. //////////////////////////////////////////////////////////////////////////////
  2712. STDMETHODIMP
  2713. CClusCfgWizard::HrGetCompletionStatus(
  2714. OBJECTCOOKIE ocTaskIn
  2715. , HRESULT * phrStatusOut
  2716. )
  2717. {
  2718. TraceFunc( "" );
  2719. HRESULT hr = S_OK;
  2720. IStandardInfo* psi = NULL;
  2721. IUnknown* punk = NULL;
  2722. hr = THR( m_pom->GetObject( DFGUID_StandardInfo, ocTaskIn, &punk ) );
  2723. if ( FAILED( hr ) )
  2724. {
  2725. goto Cleanup;
  2726. }
  2727. hr = THR( punk->TypeSafeQI( IStandardInfo, &psi ) );
  2728. if ( FAILED( hr ) )
  2729. {
  2730. goto Cleanup;
  2731. }
  2732. hr = THR( psi->GetStatus( phrStatusOut ) );
  2733. if ( FAILED( hr ) )
  2734. {
  2735. goto Cleanup;
  2736. }
  2737. Cleanup:
  2738. if ( punk != NULL )
  2739. {
  2740. punk->Release();
  2741. }
  2742. if ( psi != NULL )
  2743. {
  2744. psi->Release();
  2745. }
  2746. HRETURN( hr );
  2747. } //*** CClusCfgWizard::HrGetCompletionStatus
  2748. //////////////////////////////////////////////////////////////////////////////
  2749. //++
  2750. //
  2751. // CClusCfgWizard::HrReleaseCompletionObject
  2752. //
  2753. // Description:
  2754. // Release a completion task that's no longer needed.
  2755. //
  2756. // Arguments:
  2757. // ocTaskIn
  2758. // The task's cookie, obtained from HrGetCompletionCookie.
  2759. //
  2760. // Return Values:
  2761. // S_OK
  2762. // Failure
  2763. //
  2764. //--
  2765. //////////////////////////////////////////////////////////////////////////////
  2766. STDMETHODIMP
  2767. CClusCfgWizard::HrReleaseCompletionObject(
  2768. OBJECTCOOKIE ocTaskIn
  2769. )
  2770. {
  2771. TraceFunc( "" );
  2772. HRESULT hr = S_OK;
  2773. hr = THR( m_pom->RemoveObject( ocTaskIn ) );
  2774. if ( FAILED( hr ) )
  2775. {
  2776. goto Cleanup;
  2777. }
  2778. Cleanup:
  2779. HRETURN( hr );
  2780. } //*** CClusCfgWizard::HrReleaseCompletionObject
  2781. //****************************************************************************
  2782. //
  2783. // Non-COM public methods: connection point access
  2784. //
  2785. //****************************************************************************
  2786. //////////////////////////////////////////////////////////////////////////////
  2787. //++
  2788. //
  2789. // CClusCfgWizard::HrAdvise
  2790. //
  2791. // Description:
  2792. // Hook up an event sink to receive notifications from the middle tier.
  2793. //
  2794. // Arguments:
  2795. // riidConnectionIn - The type of event sink.
  2796. // punkConnectionIn - The event sink instance to connect.
  2797. // pdwCookieOut - The cookie to use for disconnecting.
  2798. //
  2799. // Return Values:
  2800. // S_OK
  2801. // Failure
  2802. //
  2803. //--
  2804. //////////////////////////////////////////////////////////////////////////////
  2805. STDMETHODIMP
  2806. CClusCfgWizard::HrAdvise(
  2807. REFIID riidConnectionIn
  2808. , IUnknown * punkConnectionIn
  2809. , DWORD * pdwCookieOut
  2810. )
  2811. {
  2812. TraceFunc( "" );
  2813. HRESULT hr = S_OK;
  2814. IConnectionPoint * pConnection = NULL;
  2815. hr = THR( m_pcpc->FindConnectionPoint( riidConnectionIn, &pConnection ) );
  2816. if ( FAILED( hr ) )
  2817. {
  2818. goto Cleanup;
  2819. }
  2820. hr = THR( pConnection->Advise( punkConnectionIn, pdwCookieOut ) );
  2821. if ( FAILED( hr ) )
  2822. {
  2823. goto Cleanup;
  2824. }
  2825. Cleanup:
  2826. if ( pConnection != NULL )
  2827. {
  2828. pConnection->Release();
  2829. }
  2830. HRETURN( hr );
  2831. } //*** CClusCfgWizard::HrAdvise
  2832. //////////////////////////////////////////////////////////////////////////////
  2833. //++
  2834. //
  2835. // CClusCfgWizard::HrUnadvise
  2836. //
  2837. // Description:
  2838. // Disconnect an event sink from the middle tier.
  2839. //
  2840. // Arguments:
  2841. // riidConnectionIn - The type of event sink.
  2842. // dwCookieIn - The event sink's cookie from HrAdvise.
  2843. //
  2844. // Return Values:
  2845. // S_OK
  2846. // Failure
  2847. //
  2848. //--
  2849. //////////////////////////////////////////////////////////////////////////////
  2850. STDMETHODIMP
  2851. CClusCfgWizard::HrUnadvise(
  2852. REFIID riidConnectionIn
  2853. , DWORD dwCookieIn
  2854. )
  2855. {
  2856. TraceFunc( "" );
  2857. HRESULT hr = S_OK;
  2858. IConnectionPoint * pConnection = NULL;
  2859. hr = THR( m_pcpc->FindConnectionPoint( riidConnectionIn, &pConnection ) );
  2860. if ( FAILED( hr ) )
  2861. {
  2862. goto Cleanup;
  2863. }
  2864. hr = THR( pConnection->Unadvise( dwCookieIn ) );
  2865. if ( FAILED( hr ) )
  2866. {
  2867. goto Cleanup;
  2868. }
  2869. Cleanup:
  2870. if ( pConnection != NULL )
  2871. {
  2872. pConnection->Release();
  2873. }
  2874. HRETURN( hr );
  2875. } //*** CClusCfgWizard::HrUnadvise
  2876. //****************************************************************************
  2877. //
  2878. // Non-COM public methods: miscellaneous
  2879. //
  2880. //****************************************************************************
  2881. //////////////////////////////////////////////////////////////////////////////
  2882. //++
  2883. //
  2884. // CClusCfgWizard::HrCreateMiddleTierObjects
  2885. //
  2886. // Description:
  2887. //
  2888. // Arguments:
  2889. // None.
  2890. //
  2891. // Return Values:
  2892. // S_OK
  2893. // Failure
  2894. //
  2895. //--
  2896. //////////////////////////////////////////////////////////////////////////////
  2897. STDMETHODIMP
  2898. CClusCfgWizard::HrCreateMiddleTierObjects()
  2899. {
  2900. TraceFunc( "" );
  2901. HRESULT hr = S_OK;
  2902. size_t idxNode = 0;
  2903. hr = STHR( HrGetClusterCookie( NULL ) );
  2904. if ( FAILED( hr ) )
  2905. {
  2906. goto Cleanup;
  2907. }
  2908. for ( idxNode = 0; idxNode < m_ncaNodes.Count(); ++idxNode )
  2909. {
  2910. hr = STHR( HrGetNodeCookie( idxNode, NULL ) );
  2911. if ( FAILED( hr ) )
  2912. {
  2913. goto Cleanup;
  2914. }
  2915. }
  2916. hr = S_OK;
  2917. Cleanup:
  2918. HRETURN( hr );
  2919. } //*** CClusCfgWizard::HrCreateMiddleTierObjects
  2920. //////////////////////////////////////////////////////////////////////////////
  2921. //++
  2922. //
  2923. // CClusCfgWizard::FHasClusterName
  2924. //
  2925. // Description:
  2926. //
  2927. // Arguments:
  2928. // None.
  2929. //
  2930. // Return Values:
  2931. // S_OK
  2932. // Failure
  2933. //
  2934. //--
  2935. //////////////////////////////////////////////////////////////////////////////
  2936. BOOL
  2937. CClusCfgWizard::FHasClusterName() const
  2938. {
  2939. TraceFunc( "" );
  2940. RETURN( m_ncCluster.FHasName() );
  2941. } //*** CClusCfgWizard::FHasClusterName
  2942. //////////////////////////////////////////////////////////////////////////////
  2943. //++
  2944. //
  2945. // CClusCfgWizard::FDefaultedClusterDomain
  2946. //
  2947. // Description:
  2948. //
  2949. // Arguments:
  2950. // None.
  2951. //
  2952. // Return Values:
  2953. // S_OK
  2954. // Failure
  2955. //
  2956. //--
  2957. //////////////////////////////////////////////////////////////////////////////
  2958. BOOL
  2959. CClusCfgWizard::FDefaultedClusterDomain() const
  2960. {
  2961. TraceFunc( "" );
  2962. RETURN( m_fDefaultedDomain );
  2963. } //*** CClusCfgWizard::FHasClusterName
  2964. //////////////////////////////////////////////////////////////////////////////
  2965. //++
  2966. //
  2967. // CClusCfgWizard::HrFilterNodesWithBadDomains
  2968. //
  2969. // Description:
  2970. //
  2971. // Arguments:
  2972. // None.
  2973. //
  2974. // Return Values:
  2975. // S_OK
  2976. // Failure
  2977. //
  2978. //--
  2979. //////////////////////////////////////////////////////////////////////////////
  2980. STDMETHODIMP
  2981. CClusCfgWizard::HrFilterNodesWithBadDomains( BSTR* pbstrBadNodesOut )
  2982. {
  2983. TraceFunc( "" );
  2984. HRESULT hr = S_OK;
  2985. BSTR bstrCurrentList = NULL;
  2986. NamedCookieArray ncaUnfilteredNodes;
  2987. Assert( pbstrBadNodesOut != NULL );
  2988. if ( pbstrBadNodesOut == NULL )
  2989. {
  2990. hr = THR( E_POINTER );
  2991. goto Cleanup;
  2992. }
  2993. *pbstrBadNodesOut = NULL;
  2994. ncaUnfilteredNodes.Swap( m_ncaNodes );
  2995. for ( NamedCookieArray::Iterator it = ncaUnfilteredNodes.ItBegin(); it != ncaUnfilteredNodes.ItEnd(); ++it )
  2996. {
  2997. bool fDomainValid = true;
  2998. hr = STHR( HrIsValidFQN( ( *it ).bstrName, true ) );
  2999. if ( FAILED( hr ) )
  3000. {
  3001. goto Cleanup;
  3002. }
  3003. else if ( hr == S_OK )
  3004. {
  3005. size_t idxNodeDomain = 0;
  3006. hr = THR( HrFindDomainInFQN( ( *it ).bstrName, &idxNodeDomain ) );
  3007. if ( FAILED( hr ) )
  3008. {
  3009. goto Cleanup;
  3010. }
  3011. hr = STHR( HrIsCompatibleNodeDomain( ( *it ).bstrName + idxNodeDomain ) );
  3012. if ( FAILED( hr ) )
  3013. {
  3014. goto Cleanup;
  3015. }
  3016. fDomainValid = ( hr == S_OK );
  3017. if ( fDomainValid )
  3018. {
  3019. // KB: 18-Oct-2001 jfranco bug #477514
  3020. // The wizard's supposed to show node domains to the user only when they're invalid,
  3021. // so remove the domain from the node name.
  3022. BSTR bstrShortName = NULL;
  3023. hr = THR( HrExtractPrefixFromFQN( ( *it ).bstrName, &bstrShortName ) );
  3024. if ( FAILED( hr ) )
  3025. {
  3026. goto Cleanup;
  3027. }
  3028. TraceSysFreeString( ( *it ).bstrName );
  3029. ( *it ).bstrName = bstrShortName;
  3030. }
  3031. } // if: node name has a domain
  3032. if ( fDomainValid ) // Domain is okay, so put into filtered array.
  3033. {
  3034. hr = THR( m_ncaNodes.HrPushBack( ( *it ) ) );
  3035. if ( FAILED( hr ) )
  3036. {
  3037. goto Cleanup;
  3038. }
  3039. }
  3040. else // Domain doesn't match; add to bad list.
  3041. {
  3042. if ( *pbstrBadNodesOut == NULL ) // First name in bad list.
  3043. {
  3044. *pbstrBadNodesOut = TraceSysAllocString( ( *it ).bstrName );
  3045. if ( *pbstrBadNodesOut == NULL )
  3046. {
  3047. hr = THR( E_OUTOFMEMORY );
  3048. goto Cleanup;
  3049. }
  3050. }
  3051. else // Append another name to non-empty bad list.
  3052. {
  3053. TraceSysFreeString( bstrCurrentList );
  3054. bstrCurrentList = *pbstrBadNodesOut;
  3055. *pbstrBadNodesOut = NULL;
  3056. hr = THR( HrFormatStringIntoBSTR(
  3057. L"%1!ws!; %2!ws!"
  3058. , pbstrBadNodesOut
  3059. , bstrCurrentList
  3060. , ( *it ).bstrName
  3061. ) );
  3062. if ( FAILED( hr ) )
  3063. {
  3064. goto Cleanup;
  3065. }
  3066. } // else: append name to bad list
  3067. } // else: mismatched domain
  3068. } // for: each unfiltered node
  3069. Cleanup:
  3070. TraceSysFreeString( bstrCurrentList );
  3071. HRETURN( hr );
  3072. } //*** CClusCfgWizard::HrFilterNodesWithBadDomains
  3073. /*
  3074. //////////////////////////////////////////////////////////////////////////////
  3075. //++
  3076. //
  3077. // CClusCfgWizard::HrReadSettings
  3078. //
  3079. // Description:
  3080. // Read the saved settings from the registry. If there are no saved
  3081. // setting then we want to do a full configuration.
  3082. //
  3083. // Arguments:
  3084. // pecsSettingOut
  3085. // What is the saved setting?
  3086. //
  3087. // pfValuePresentOut
  3088. // Was the value present in the registry?
  3089. //
  3090. // Return Values:
  3091. // S_OK
  3092. // Success
  3093. //
  3094. //--
  3095. //////////////////////////////////////////////////////////////////////////////
  3096. HRESULT
  3097. CClusCfgWizard::HrReadSettings(
  3098. EConfigurationSettings * pecsSettingOut
  3099. , BOOL * pfValuePresentOut // = NULL
  3100. )
  3101. {
  3102. TraceFunc( "" );
  3103. Assert( pecsSettingOut != NULL );
  3104. HRESULT hr = S_OK;
  3105. DWORD sc;
  3106. HKEY hKey = NULL;
  3107. DWORD dwType;
  3108. DWORD dwData;
  3109. DWORD cbData = sizeof( dwData );
  3110. //
  3111. // Default to doing a full config.
  3112. //
  3113. *pecsSettingOut = csFullConfig;
  3114. //
  3115. // Default to the value not being present.
  3116. //
  3117. if ( pfValuePresentOut != NULL )
  3118. {
  3119. *pfValuePresentOut = FALSE;
  3120. } // if:
  3121. sc = RegOpenKeyExW( HKEY_CURRENT_USER, USER_REGISTRY_SETTINGS_KEY, 0, KEY_READ, &hKey );
  3122. if ( sc == ERROR_FILE_NOT_FOUND )
  3123. {
  3124. hr = S_FALSE;
  3125. goto Cleanup;
  3126. } // if:
  3127. //
  3128. // If we fail for any other reason log it and leave.
  3129. //
  3130. if ( sc != ERROR_SUCCESS )
  3131. {
  3132. LogMsg( L"[WIZ] RegOpenKeyEx() for %ws failed. (hr = %#08x)", USER_REGISTRY_SETTINGS_KEY, HRESULT_FROM_WIN32( TW32( sc ) ) );
  3133. goto Cleanup;
  3134. } // if:
  3135. //
  3136. // Now that the key is open we need to read the value.
  3137. //
  3138. sc = RegQueryValueExW( hKey, CONFIGURATION_TYPE, NULL, &dwType, (LPBYTE) &dwData, &cbData );
  3139. if ( sc == ERROR_FILE_NOT_FOUND )
  3140. {
  3141. //
  3142. // It's okay if the value is not found.
  3143. //
  3144. goto Cleanup;
  3145. } // if:
  3146. else if ( sc == ERROR_SUCCESS )
  3147. {
  3148. Assert( dwType == REG_DWORD )
  3149. //
  3150. // The value was present. Tell the caller if they cared to ask...
  3151. //
  3152. if ( pfValuePresentOut != NULL )
  3153. {
  3154. *pfValuePresentOut = TRUE;
  3155. } // if:
  3156. //
  3157. // If there was a stored value then we need to return it to the caller.
  3158. //
  3159. *pecsSettingOut = (EConfigurationSettings) dwData;
  3160. } // else if:
  3161. else
  3162. {
  3163. TW32( sc );
  3164. hr = HRESULT_FROM_WIN32( sc );
  3165. goto Cleanup;
  3166. } // else:
  3167. Cleanup:
  3168. if ( hKey != NULL )
  3169. {
  3170. RegCloseKey( hKey );
  3171. } // if:
  3172. HRETURN( hr );
  3173. } //*** CClusCfgWizard::HrReadSettings
  3174. //////////////////////////////////////////////////////////////////////////////
  3175. //++
  3176. //
  3177. // CClusCfgWizard::HrWriteSettings
  3178. //
  3179. // Description:
  3180. // Write the settings into the registry.
  3181. //
  3182. // Arguments:
  3183. // ecsSettingIn
  3184. // The setting to write.
  3185. //
  3186. // fDeleteValueIn
  3187. // Should the value be deleted and therefore stop being the default
  3188. // setting.
  3189. //
  3190. // Return Values:
  3191. // S_OK
  3192. // Success
  3193. //
  3194. //--
  3195. //////////////////////////////////////////////////////////////////////////////
  3196. HRESULT
  3197. CClusCfgWizard::HrWriteSettings(
  3198. EConfigurationSettings ecsSettingIn
  3199. , BOOL fDeleteValueIn // = FALSE
  3200. )
  3201. {
  3202. TraceFunc( "" );
  3203. HRESULT hr = S_OK;
  3204. DWORD sc;
  3205. HKEY hKey = NULL;
  3206. sc = RegCreateKeyExW( HKEY_CURRENT_USER, USER_REGISTRY_SETTINGS_KEY, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL );
  3207. if ( sc != ERROR_SUCCESS )
  3208. {
  3209. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  3210. LogMsg( L"[WIZ] RegCreateKeyExW() for %ws failed. (hr = %#08x)", USER_REGISTRY_SETTINGS_KEY, hr );
  3211. goto Cleanup;
  3212. } // if:
  3213. //
  3214. // Only save the data if we are not going to delete the value from the registry.
  3215. //
  3216. if ( fDeleteValueIn == FALSE )
  3217. {
  3218. //
  3219. // Now that the key is open we need to write the value.
  3220. //
  3221. sc = RegSetValueExW( hKey, CONFIGURATION_TYPE, NULL, REG_DWORD, (LPBYTE) &ecsSettingIn, sizeof( ecsSettingIn ) );
  3222. if ( sc != ERROR_SUCCESS )
  3223. {
  3224. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  3225. goto Cleanup;
  3226. } // if:
  3227. } // if:
  3228. else
  3229. {
  3230. sc = RegDeleteValueW( hKey, CONFIGURATION_TYPE );
  3231. if ( ( sc != ERROR_SUCCESS ) && ( sc != ERROR_FILE_NOT_FOUND ) )
  3232. {
  3233. TW32( sc );
  3234. hr = HRESULT_FROM_WIN32( sc );
  3235. goto Cleanup;
  3236. } // if:
  3237. } // else:
  3238. Cleanup:
  3239. if ( hKey != NULL )
  3240. {
  3241. RegCloseKey( hKey );
  3242. } // if:
  3243. HRETURN( hr );
  3244. } //*** CClusCfgWizard::HrWriteSettings
  3245. */
  3246. //****************************************************************************
  3247. //
  3248. // INotifyUI
  3249. //
  3250. //****************************************************************************
  3251. //////////////////////////////////////////////////////////////////////////////
  3252. //++
  3253. //
  3254. // CClusCfgWizard::ObjectChanged
  3255. //
  3256. // Description:
  3257. //
  3258. // Arguments:
  3259. // cookieIn
  3260. //
  3261. // Return Values:
  3262. // S_OK
  3263. // Failure
  3264. //
  3265. //--
  3266. //////////////////////////////////////////////////////////////////////////////
  3267. STDMETHODIMP
  3268. CClusCfgWizard::ObjectChanged(
  3269. OBJECTCOOKIE cookieIn
  3270. )
  3271. {
  3272. TraceFunc( "[INotifyUI]" );
  3273. HRESULT hr = S_OK;
  3274. HRESULT hrResult;
  3275. BOOL fSuccess;
  3276. if ( cookieIn == m_cookieCompletion )
  3277. {
  3278. THR( HrGetCompletionStatus( m_cookieCompletion, &hrResult ) );
  3279. fSuccess = SetEvent( m_hCancelCleanupEvent );
  3280. if ( fSuccess == FALSE )
  3281. {
  3282. hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
  3283. } // if:
  3284. } // if:
  3285. HRETURN( hr );
  3286. } //*** CClusCfgWizard::ObjectChanged