Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2006 lines
49 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // TaskCommitClusterChanges.cpp
  7. //
  8. // Description:
  9. // CTaskCommitClusterChanges implementation.
  10. //
  11. // Maintained By:
  12. // Galen Barbee (GalenB) 02-FEB-2000
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. #include "pch.h"
  16. #include "TaskCommitClusterChanges.h"
  17. DEFINE_THISCLASS("CTaskCommitClusterChanges")
  18. // ************************************************************************
  19. //
  20. // Constructor / Destructor
  21. //
  22. // ************************************************************************
  23. //////////////////////////////////////////////////////////////////////////////
  24. //
  25. // HRESULT
  26. // CTaskCommitClusterChanges::S_HrCreateInstance(
  27. // IUnknown ** ppunkOut
  28. // )
  29. //
  30. //////////////////////////////////////////////////////////////////////////////
  31. HRESULT
  32. CTaskCommitClusterChanges::S_HrCreateInstance(
  33. IUnknown ** ppunkOut
  34. )
  35. {
  36. TraceFunc( "" );
  37. Assert( ppunkOut != NULL );
  38. HRESULT hr;
  39. CTaskCommitClusterChanges * ptccc = new CTaskCommitClusterChanges;
  40. if ( ptccc != NULL )
  41. {
  42. hr = THR( ptccc->Init() );
  43. if ( SUCCEEDED( hr ) )
  44. {
  45. hr = THR( ptccc->TypeSafeQI( IUnknown, ppunkOut ) );
  46. }
  47. ptccc->Release();
  48. }
  49. else
  50. {
  51. hr = E_OUTOFMEMORY;
  52. }
  53. HRETURN( hr );
  54. } // S_HrCreateInstance()
  55. //////////////////////////////////////////////////////////////////////////////
  56. //
  57. // CTaskCommitClusterChanges::CTaskCommitClusterChanges( void )
  58. //
  59. //////////////////////////////////////////////////////////////////////////////
  60. CTaskCommitClusterChanges::CTaskCommitClusterChanges( void )
  61. {
  62. TraceFunc( "" );
  63. InterlockedIncrement( &g_cObjects );
  64. TraceFuncExit();
  65. } // CTaskCommitClusterChanges()
  66. //////////////////////////////////////////////////////////////////////////////
  67. //
  68. // STDMETHODIMP
  69. // CTaskCommitClusterChanges::Init( void )
  70. //
  71. //////////////////////////////////////////////////////////////////////////////
  72. STDMETHODIMP
  73. CTaskCommitClusterChanges::Init( void )
  74. {
  75. TraceFunc( "" );
  76. HRESULT hr = S_OK;
  77. // IUnknown stuff
  78. Assert( m_cRef == 0 );
  79. AddRef(); // Add one count
  80. // IDoTask / ITaskCommitClusterChanges
  81. Assert( m_cookie == 0 );
  82. Assert( m_pcccb == NULL );
  83. Assert( m_pcookies == NULL );
  84. Assert( m_cNodes == 0 );
  85. Assert( m_event == NULL );
  86. Assert( m_cookieCluster == NULL );
  87. Assert( m_cookieFormingNode == NULL );
  88. Assert( m_punkFormingNode == NULL );
  89. Assert( m_bstrClusterName == NULL );
  90. Assert( m_bstrClusterBindingString == NULL );
  91. Assert( m_bstrAccountName == NULL );
  92. Assert( m_bstrAccountPassword == NULL );
  93. Assert( m_bstrAccountDomain == NULL );
  94. Assert( m_ulIPAddress == 0 );
  95. Assert( m_ulSubnetMask == 0 );
  96. Assert( m_bstrNetworkUID == 0 );
  97. Assert( m_pen == NULL );
  98. Assert( m_pnui == NULL );
  99. Assert( m_pom == NULL );
  100. Assert( m_ptm == NULL );
  101. Assert( m_pcm == NULL );
  102. // INotifyUI
  103. Assert( m_cNodes == 0 );
  104. Assert( m_hrStatus == S_OK );
  105. HRETURN( hr );
  106. } // Init()
  107. //////////////////////////////////////////////////////////////////////////////
  108. //
  109. // CTaskCommitClusterChanges::~CTaskCommitClusterChanges()
  110. //
  111. //////////////////////////////////////////////////////////////////////////////
  112. CTaskCommitClusterChanges::~CTaskCommitClusterChanges()
  113. {
  114. TraceFunc( "" );
  115. // m_cRef
  116. // m_cookie
  117. if ( m_pcccb != NULL )
  118. {
  119. m_pcccb->Release();
  120. }
  121. if ( m_pcookies != NULL )
  122. {
  123. TraceFree( m_pcookies );
  124. }
  125. // m_cNodes
  126. if ( m_event != NULL )
  127. {
  128. CloseHandle( m_event );
  129. }
  130. // m_cookieCluster
  131. // m_cookieFormingNode
  132. if ( m_punkFormingNode != NULL )
  133. {
  134. m_punkFormingNode->Release();
  135. }
  136. TraceSysFreeString( m_bstrClusterName );
  137. TraceSysFreeString( m_bstrAccountName );
  138. TraceSysFreeString( m_bstrClusterBindingString );
  139. if ( m_bstrAccountPassword != NULL )
  140. {
  141. DWORD dwLen = SysStringLen( m_bstrAccountPassword );
  142. // need to trash the password.
  143. memset( m_bstrAccountPassword, 0, dwLen * sizeof( WCHAR ) );
  144. TraceSysFreeString( m_bstrAccountPassword );
  145. }
  146. TraceSysFreeString( m_bstrAccountDomain );
  147. // m_ulIPAddress
  148. // m_ulSubnetMask
  149. TraceSysFreeString( m_bstrNetworkUID );
  150. if ( m_pen != NULL )
  151. {
  152. m_pen->Release();
  153. }
  154. if ( m_pnui != NULL )
  155. {
  156. m_pnui->Release();
  157. }
  158. if ( m_pom != NULL )
  159. {
  160. m_pom->Release();
  161. }
  162. if ( m_ptm != NULL )
  163. {
  164. m_ptm->Release();
  165. }
  166. if ( m_pcm != NULL )
  167. {
  168. m_pcm->Release();
  169. }
  170. // m_cSubTasksDone
  171. // m_hrStatus
  172. // m_lLockCallback
  173. InterlockedDecrement( &g_cObjects );
  174. TraceFuncExit();
  175. } // ~CTaskCommitClusterChanges()
  176. // ************************************************************************
  177. //
  178. // IUnknown
  179. //
  180. // ************************************************************************
  181. //////////////////////////////////////////////////////////////////////////////
  182. //
  183. // STDMETHODIMP
  184. // CTaskCommitClusterChanges::QueryInterface(
  185. // REFIID riid,
  186. // LPVOID *ppv
  187. // )
  188. //
  189. //////////////////////////////////////////////////////////////////////////////
  190. STDMETHODIMP
  191. CTaskCommitClusterChanges::QueryInterface(
  192. REFIID riid,
  193. LPVOID *ppv
  194. )
  195. {
  196. TraceQIFunc( riid, ppv );
  197. HRESULT hr = E_NOINTERFACE;
  198. if ( IsEqualIID( riid, IID_IUnknown ) )
  199. {
  200. *ppv = static_cast< ITaskCommitClusterChanges * >( this );
  201. hr = S_OK;
  202. } // if: IUnknown
  203. else if ( IsEqualIID( riid, IID_ITaskCommitClusterChanges ) )
  204. {
  205. *ppv = TraceInterface( __THISCLASS__, ITaskCommitClusterChanges, this, 0 );
  206. hr = S_OK;
  207. } // else if: ITaskCommitClusterChanges
  208. else if ( IsEqualIID( riid, IID_IDoTask ) )
  209. {
  210. *ppv = TraceInterface( __THISCLASS__, IDoTask, this, 0 );
  211. hr = S_OK;
  212. } // else if: IDoTask
  213. else if ( IsEqualIID( riid, IID_INotifyUI ) )
  214. {
  215. *ppv = TraceInterface( __THISCLASS__, INotifyUI, this, 0 );
  216. hr = S_OK;
  217. } // else if: INotifyUI
  218. else if ( IsEqualIID( riid, IID_IClusCfgCallback ) )
  219. {
  220. *ppv = TraceInterface( __THISCLASS__, IClusCfgCallback, this, 0 );
  221. hr = S_OK;
  222. } // else if: IClusCfgCallback
  223. if ( SUCCEEDED( hr ) )
  224. {
  225. ((IUnknown*) *ppv)->AddRef();
  226. } // if: success
  227. QIRETURN_IGNORESTDMARSHALLING( hr, riid );
  228. } // QueryInterface()
  229. //////////////////////////////////////////////////////////////////////////////
  230. //
  231. // STDMETHODIMP_(ULONG)
  232. // CTaskCommitClusterChanges::AddRef( void )
  233. //
  234. //////////////////////////////////////////////////////////////////////////////
  235. STDMETHODIMP_(ULONG)
  236. CTaskCommitClusterChanges::AddRef( void )
  237. {
  238. TraceFunc( "[IUnknown]" );
  239. InterlockedIncrement( &m_cRef );
  240. RETURN( m_cRef );
  241. } // AddRef()
  242. //////////////////////////////////////////////////////////////////////////////
  243. //
  244. // STDMETHODIMP_(ULONG)
  245. // CTaskCommitClusterChanges::Release( void )
  246. //
  247. //////////////////////////////////////////////////////////////////////////////
  248. STDMETHODIMP_(ULONG)
  249. CTaskCommitClusterChanges::Release( void )
  250. {
  251. TraceFunc( "[IUnknown]" );
  252. InterlockedDecrement( &m_cRef );
  253. if ( m_cRef )
  254. RETURN( m_cRef );
  255. TraceDo( delete this );
  256. RETURN(0);
  257. } // Release()
  258. // ************************************************************************
  259. //
  260. // IDoTask / ITaskCommitClusterChanges
  261. //
  262. // ************************************************************************
  263. //////////////////////////////////////////////////////////////////////////////
  264. //
  265. // STDMETHODIMP
  266. // CTaskCommitClusterChanges::BeginTask( void );
  267. //
  268. //////////////////////////////////////////////////////////////////////////////
  269. STDMETHODIMP
  270. CTaskCommitClusterChanges::BeginTask( void )
  271. {
  272. TraceFunc( "[IDoTask]" );
  273. HRESULT hr;
  274. OBJECTCOOKIE cookieDummy;
  275. IServiceProvider * psp = NULL;
  276. IUnknown * punk = NULL;
  277. IConnectionPointContainer * pcpc = NULL;
  278. IConnectionPoint * pcp = NULL;
  279. TraceInitializeThread( L"TaskCommitClusterChanges" );
  280. //
  281. // Gather the managers we need to complete the task.
  282. //
  283. hr = THR( CoCreateInstance( CLSID_ServiceManager,
  284. NULL,
  285. CLSCTX_INPROC_SERVER,
  286. TypeSafeParams( IServiceProvider, &psp )
  287. ) );
  288. if ( FAILED( hr ) )
  289. goto Cleanup;
  290. hr = THR( psp->TypeSafeQS( CLSID_NotificationManager,
  291. IConnectionPointContainer,
  292. &pcpc
  293. ) );
  294. if ( FAILED( hr ) )
  295. goto Cleanup;
  296. pcpc = TraceInterface( L"CTaskCommitClusterChanges!IConnectionPointContainer", IConnectionPointContainer, pcpc, 1 );
  297. hr = THR( pcpc->FindConnectionPoint( IID_INotifyUI, &pcp ) );
  298. if ( FAILED( hr ) )
  299. goto Cleanup;
  300. pcp = TraceInterface( L"CTaskCommitClusterChanges!IConnectionPoint", IConnectionPoint, pcp, 1 );
  301. hr = THR( pcp->TypeSafeQI( INotifyUI, &m_pnui ) );
  302. if ( FAILED( hr ) )
  303. goto Cleanup;
  304. // TraceMoveFromMemoryList( m_pnui, g_GlobalMemoryList );
  305. m_pnui = TraceInterface( L"CTaskCommitClusterChanges!INotifyUI", INotifyUI, m_pnui, 1 );
  306. hr = THR( psp->TypeSafeQS( CLSID_TaskManager,
  307. ITaskManager,
  308. &m_ptm
  309. ) );
  310. if ( FAILED( hr ) )
  311. goto Cleanup;
  312. hr = THR( psp->TypeSafeQS( CLSID_ObjectManager,
  313. IObjectManager,
  314. &m_pom
  315. ) );
  316. if ( FAILED( hr ) )
  317. goto Cleanup;
  318. hr = THR( psp->TypeSafeQS( CLSID_ClusterConnectionManager, IConnectionManager, &m_pcm ) );
  319. if ( FAILED( hr ) )
  320. goto Cleanup;
  321. //
  322. // Release the service manager.
  323. //
  324. psp->Release();
  325. psp = NULL;
  326. //
  327. // Get the enum of the nodes.
  328. //
  329. hr = THR( m_pom->FindObject( CLSID_NodeType,
  330. m_cookieCluster,
  331. NULL,
  332. DFGUID_EnumNodes,
  333. &cookieDummy,
  334. &punk
  335. ) );
  336. if ( FAILED( hr ) )
  337. goto Cleanup;
  338. hr = THR( punk->TypeSafeQI( IEnumNodes, &m_pen ) );
  339. if ( FAILED( hr ) )
  340. goto Cleanup;
  341. //
  342. // Compare and push information to the nodes.
  343. //
  344. hr = THR( HrCompareAndPushInformationToNodes() );
  345. if ( FAILED( hr ) )
  346. goto Cleanup;
  347. //
  348. // Gather information about the cluster we are to form/join.
  349. //
  350. hr = THR( HrGatherClusterInformation() );
  351. if ( FAILED( hr ) )
  352. goto Cleanup;
  353. //
  354. // Check to see if we need to "form" a cluster first.
  355. //
  356. if ( m_punkFormingNode != NULL )
  357. {
  358. hr = THR( HrFormFirstNode() );
  359. if ( FAILED( hr ) )
  360. goto Cleanup;
  361. } // if: m_punkFormingNode
  362. //
  363. // Join the additional nodes.
  364. //
  365. hr = THR( HrAddJoiningNodes() );
  366. if ( FAILED( hr ) )
  367. goto Cleanup;
  368. Cleanup:
  369. if ( m_cookie != 0 )
  370. {
  371. if ( m_pom != NULL )
  372. {
  373. HRESULT hr2;
  374. IUnknown * punk;
  375. hr2 = THR( m_pom->GetObject( DFGUID_StandardInfo,
  376. m_cookie,
  377. &punk
  378. ) );
  379. if ( SUCCEEDED( hr2 ) )
  380. {
  381. IStandardInfo * psi;
  382. hr2 = THR( punk->TypeSafeQI( IStandardInfo, &psi ) );
  383. punk->Release();
  384. if ( SUCCEEDED( hr2 ) )
  385. {
  386. hr2 = THR( psi->SetStatus( hr ) );
  387. psi->Release();
  388. }
  389. }
  390. }
  391. if ( m_pnui != NULL )
  392. {
  393. // Signal that the task completed.
  394. THR( m_pnui->ObjectChanged( m_cookie ) );
  395. }
  396. }
  397. if ( punk != NULL )
  398. {
  399. punk->Release();
  400. }
  401. if ( psp != NULL )
  402. {
  403. psp->Release();
  404. }
  405. if ( pcpc != NULL )
  406. {
  407. pcpc->Release();
  408. }
  409. if ( pcp != NULL )
  410. {
  411. pcp->Release();
  412. }
  413. HRETURN( hr );
  414. } // BeginTask()
  415. //////////////////////////////////////////////////////////////////////////////
  416. //
  417. // STDMETHODIMP
  418. // CTaskCommitClusterChanges::StopTask( void )
  419. //
  420. //////////////////////////////////////////////////////////////////////////////
  421. STDMETHODIMP
  422. CTaskCommitClusterChanges::StopTask( void )
  423. {
  424. TraceFunc( "[IDoTask]" );
  425. HRESULT hr = S_OK;
  426. HRETURN( hr );
  427. } //*** CTaskCommitClusterChanges::StopTask
  428. //////////////////////////////////////////////////////////////////////////////
  429. //
  430. // STDMETHODIMP
  431. // CTaskCommitClusterChanges::SetCookie(
  432. // OBJECTCOOKIE cookieIn
  433. // )
  434. //
  435. //////////////////////////////////////////////////////////////////////////////
  436. STDMETHODIMP
  437. CTaskCommitClusterChanges::SetCookie(
  438. OBJECTCOOKIE cookieIn
  439. )
  440. {
  441. TraceFunc( "[ITaskCommitClusterChanges]" );
  442. HRESULT hr = S_OK;
  443. m_cookie = cookieIn;
  444. HRETURN( hr );
  445. } // SetCookie()
  446. //////////////////////////////////////////////////////////////////////////////
  447. //
  448. // STDMETHODIMP
  449. // CTaskCommitClusterChanges::SetClusterCookie(
  450. // OBJECTCOOKIE cookieClusterIn
  451. // )
  452. //
  453. //////////////////////////////////////////////////////////////////////////////
  454. STDMETHODIMP
  455. CTaskCommitClusterChanges::SetClusterCookie(
  456. OBJECTCOOKIE cookieClusterIn
  457. )
  458. {
  459. TraceFunc( "[ITaskCommitClusterChanges]" );
  460. HRESULT hr = S_OK;
  461. m_cookieCluster = cookieClusterIn;
  462. HRETURN( hr );
  463. } // SetClusterCookie()
  464. //////////////////////////////////////////////////////////////////////////////
  465. //
  466. // STDMETHODIMP
  467. // CTaskCommitClusterChanges::SetJoining( void )
  468. //
  469. //////////////////////////////////////////////////////////////////////////////
  470. STDMETHODIMP
  471. CTaskCommitClusterChanges::SetJoining( void )
  472. {
  473. TraceFunc( "[ITaskCommitClusterChanges]" );
  474. HRESULT hr = S_OK;
  475. m_fJoining = TRUE;
  476. HRETURN( hr );
  477. } // SetJoining()
  478. //****************************************************************************
  479. //
  480. // IClusCfgCallback
  481. //
  482. //****************************************************************************
  483. //////////////////////////////////////////////////////////////////////////////
  484. //
  485. // STDMETHODIMP
  486. // CTaskCommitClusterChanges::SendStatusReport(
  487. // LPCWSTR pcszNodeNameIn
  488. // , CLSID clsidTaskMajorIn
  489. // , CLSID clsidTaskMinorIn
  490. // , ULONG ulMinIn
  491. // , ULONG ulMaxIn
  492. // , ULONG ulCurrentIn
  493. // , HRESULT hrStatusIn
  494. // , LPCWSTR pcszDescriptionIn
  495. // , FILETIME * pftTimeIn
  496. // , LPCWSTR pcszReferenceIn
  497. // )
  498. //
  499. //////////////////////////////////////////////////////////////////////////////
  500. STDMETHODIMP
  501. CTaskCommitClusterChanges::SendStatusReport(
  502. LPCWSTR pcszNodeNameIn
  503. , CLSID clsidTaskMajorIn
  504. , CLSID clsidTaskMinorIn
  505. , ULONG ulMinIn
  506. , ULONG ulMaxIn
  507. , ULONG ulCurrentIn
  508. , HRESULT hrStatusIn
  509. , LPCWSTR pcszDescriptionIn
  510. , FILETIME * pftTimeIn
  511. , LPCWSTR pcszReferenceIn
  512. )
  513. {
  514. TraceFunc( "[IClusCfgCallback]" );
  515. HRESULT hr = S_OK;
  516. IServiceProvider * psp = NULL;
  517. IConnectionPointContainer * pcpc = NULL;
  518. IConnectionPoint * pcp = NULL;
  519. FILETIME ft;
  520. if ( m_pcccb == NULL )
  521. {
  522. //
  523. // Collect the manager we need to complete this task.
  524. //
  525. hr = THR( CoCreateInstance( CLSID_ServiceManager,
  526. NULL,
  527. CLSCTX_INPROC_SERVER,
  528. TypeSafeParams( IServiceProvider, &psp )
  529. ) );
  530. if ( FAILED( hr ) )
  531. goto Cleanup;
  532. hr = THR( psp->TypeSafeQS( CLSID_NotificationManager,
  533. IConnectionPointContainer,
  534. &pcpc
  535. ) );
  536. if ( FAILED( hr ) )
  537. goto Cleanup;
  538. hr = THR( pcpc->FindConnectionPoint( IID_IClusCfgCallback, &pcp ) );
  539. if ( FAILED( hr ) )
  540. goto Cleanup;
  541. pcp = TraceInterface( L"CConfigurationConnection!IConnectionPoint", IConnectionPoint, pcp, 1 );
  542. hr = THR( pcp->TypeSafeQI( IClusCfgCallback, &m_pcccb ) );
  543. if ( FAILED( hr ) )
  544. goto Cleanup;
  545. m_pcccb = TraceInterface( L"CConfigurationConnection!IClusCfgCallback", IClusCfgCallback, m_pcccb, 1 );
  546. psp->Release();
  547. psp = NULL;
  548. }
  549. if ( pftTimeIn == NULL )
  550. {
  551. GetSystemTimeAsFileTime( &ft );
  552. pftTimeIn = &ft;
  553. } // if:
  554. //
  555. // Send the message!
  556. //
  557. hr = THR( m_pcccb->SendStatusReport( pcszNodeNameIn,
  558. clsidTaskMajorIn,
  559. clsidTaskMinorIn,
  560. ulMinIn,
  561. ulMaxIn,
  562. ulCurrentIn,
  563. hrStatusIn,
  564. pcszDescriptionIn,
  565. pftTimeIn,
  566. pcszReferenceIn
  567. ) );
  568. Cleanup:
  569. if ( psp != NULL )
  570. {
  571. psp->Release();
  572. }
  573. if ( pcpc != NULL )
  574. {
  575. pcpc->Release();
  576. }
  577. if ( pcp != NULL )
  578. {
  579. pcp->Release();
  580. }
  581. HRETURN( hr );
  582. } // SendStatusReport()
  583. //****************************************************************************
  584. //
  585. // INotifyUI
  586. //
  587. //****************************************************************************
  588. //////////////////////////////////////////////////////////////////////////////
  589. //
  590. // STDMETHODIMP
  591. // CTaskCommitClusterChanges::ObjectChanged(
  592. // OBJECTCOOKIE cookieIn
  593. // )
  594. //
  595. //////////////////////////////////////////////////////////////////////////////
  596. STDMETHODIMP
  597. CTaskCommitClusterChanges::ObjectChanged(
  598. OBJECTCOOKIE cookieIn
  599. )
  600. {
  601. TraceFunc( "[INotifyUI]" );
  602. BOOL b;
  603. ULONG cNodes;
  604. HRESULT hr = S_OK;
  605. for ( cNodes = 0; cNodes < m_cNodes; cNodes ++ )
  606. {
  607. if ( cookieIn == m_pcookies[ cNodes ] )
  608. {
  609. //
  610. // Make sure it won't be signalled twice.
  611. //
  612. m_pcookies[ cNodes ] = NULL;
  613. InterlockedIncrement( reinterpret_cast< long * >( &m_cSubTasksDone ) );
  614. if ( m_cSubTasksDone == m_cNodes )
  615. {
  616. //
  617. // Signal the event if all the nodes are done.
  618. //
  619. b = SetEvent( m_event );
  620. if ( !b )
  621. goto Win32Error;
  622. } // if: all done
  623. } // if: matched cookie
  624. } // for: cNodes
  625. Cleanup:
  626. HRETURN( hr );
  627. Win32Error:
  628. hr = THR( HRESULT_FROM_WIN32( GetLastError() ) );
  629. goto Cleanup;
  630. } // ObjectChanged()
  631. //****************************************************************************
  632. //
  633. // Private
  634. //
  635. //****************************************************************************
  636. //////////////////////////////////////////////////////////////////////////////
  637. //
  638. // HRESULT
  639. // CTaskCommitClusterChanges::HrCompareAndPushInformationToNodes( void )
  640. //
  641. //////////////////////////////////////////////////////////////////////////////
  642. HRESULT
  643. CTaskCommitClusterChanges::HrCompareAndPushInformationToNodes( void )
  644. {
  645. TraceFunc( "" );
  646. HRESULT hr;
  647. DWORD dwCookie;
  648. DWORD dwErr;
  649. ULONG cNodes;
  650. ULONG celtDummy;
  651. OBJECTCOOKIE cookie;
  652. OBJECTCOOKIE * pcookies = NULL;
  653. BOOL fDeterminedForming = FALSE;
  654. BSTR bstrName = NULL;
  655. BSTR bstrNotification = NULL;
  656. IUnknown * punk = NULL;
  657. IClusCfgNodeInfo * pccni = NULL;
  658. IConnectionPoint * pcp = NULL;
  659. IStandardInfo * psi = NULL;
  660. ITaskCompareAndPushInformation * ptcapi = NULL;
  661. //
  662. // Tell the UI layer that we are starting to connect to the nodes.
  663. //
  664. hr = THR( SendStatusReport( NULL,
  665. TASKID_Major_Reanalyze,
  666. TASKID_Minor_Update_Progress, // just twiddle the icon
  667. 0,
  668. 1,
  669. 0,
  670. S_OK,
  671. NULL,
  672. NULL,
  673. NULL
  674. ) );
  675. if ( FAILED( hr ) )
  676. goto Cleanup;
  677. //
  678. // Count the number of nodes.
  679. //
  680. m_cNodes = 0;
  681. Assert( hr == S_OK );
  682. while ( hr == S_OK )
  683. {
  684. hr = STHR( m_pen->Next( 1, &pccni, &celtDummy ) );
  685. if ( hr == S_FALSE )
  686. break; // end of list
  687. if ( FAILED( hr ) )
  688. goto Error;
  689. pccni->Release();
  690. pccni = NULL;
  691. m_cNodes ++;
  692. } // while: hr == S_OK
  693. //
  694. // Reset the enum to use again.
  695. //
  696. hr = THR( m_pen->Reset() );
  697. if ( FAILED( hr ) )
  698. goto Error;
  699. //
  700. // Create an event to signal when all the "push" tasks have been
  701. // completed.
  702. //
  703. m_event = CreateEvent( NULL, TRUE, FALSE, NULL );
  704. if ( m_event == NULL )
  705. {
  706. hr = THR( HRESULT_FROM_WIN32( GetLastError() ) );
  707. goto Error;
  708. }
  709. //
  710. // Register with the Notification Manager to get notified.
  711. //
  712. hr = THR( m_pnui->TypeSafeQI( IConnectionPoint,
  713. &pcp
  714. ) );
  715. if ( FAILED( hr ) )
  716. goto Error;
  717. hr = THR( pcp->Advise( static_cast< INotifyUI * >( this ), &dwCookie ) );
  718. if ( FAILED( hr ) )
  719. goto Error;
  720. //
  721. // Allocate a buffer to collect cookies
  722. //
  723. m_pcookies = reinterpret_cast< OBJECTCOOKIE * >( TraceAlloc( 0, m_cNodes * sizeof( OBJECTCOOKIE ) ) );
  724. if ( m_pcookies == NULL )
  725. goto OutOfMemory;
  726. //
  727. // This copy is to find out the status of the subtasks.
  728. //
  729. pcookies = reinterpret_cast< OBJECTCOOKIE * >( TraceAlloc( 0, m_cNodes * sizeof( OBJECTCOOKIE ) ) );
  730. if ( pcookies == NULL )
  731. goto OutOfMemory;
  732. //
  733. // Loop thru the nodes, creating cookies and compare data for that node.
  734. //
  735. Assert( hr == S_OK );
  736. for( cNodes = 0; hr == S_OK; cNodes ++ )
  737. {
  738. //
  739. // Grab the next node.
  740. //
  741. hr = STHR( m_pen->Next( 1, &pccni, &celtDummy ) );
  742. if ( hr == S_FALSE )
  743. break;
  744. if ( FAILED( hr ) )
  745. goto Error;
  746. //
  747. // Get the nodes name. We are using this to distinguish one nodes
  748. // completion cookie from another. It might also make debugging
  749. // easier (??).
  750. //
  751. hr = THR( pccni->GetName( &bstrName ) );
  752. if ( FAILED( hr ) )
  753. goto Error;
  754. TraceMemoryAddBSTR( bstrName );
  755. //
  756. // Update the notification in case something goes wrong.
  757. //
  758. hr = THR( HrFormatMessageIntoBSTR( g_hInstance,
  759. IDS_TASKID_MINOR_CONNECTING_TO_NODES,
  760. &bstrNotification,
  761. bstrName
  762. ) );
  763. if ( FAILED( hr ) )
  764. goto Cleanup;
  765. //
  766. // Create a completion cookie.
  767. //
  768. // KB: These will probably be the same cookie from TaskAnalyzeCluster.
  769. //
  770. // Wrap this because we're just generating a cookie
  771. hr = THR( m_pom->FindObject( IID_NULL,
  772. m_cookieCluster,
  773. bstrName,
  774. IID_NULL,
  775. &m_pcookies[ cNodes ],
  776. &punk // dummy
  777. ) );
  778. Assert( punk == NULL );
  779. if ( FAILED( hr ) )
  780. goto Error;
  781. //
  782. // This copy is for determining the status of the sub-tasks.
  783. //
  784. pcookies[ cNodes ] = m_pcookies[ cNodes ];
  785. //
  786. // Figure out if this node is already part of a cluster.
  787. //
  788. hr = STHR( pccni->IsMemberOfCluster() );
  789. if ( FAILED( hr ) )
  790. goto Error;
  791. //
  792. // Figure out the forming node.
  793. //
  794. if ( m_punkFormingNode == NULL // no forming node selected
  795. && !fDeterminedForming // no forming node determined
  796. && hr == S_FALSE // node isn't a member of a cluster
  797. )
  798. {
  799. //
  800. // If it isn't a member of a cluster, select it as the forming node.
  801. //
  802. Assert( m_punkFormingNode == NULL );
  803. hr = THR( pccni->TypeSafeQI( IUnknown, &m_punkFormingNode ) );
  804. if ( FAILED( hr ) )
  805. goto Error;
  806. //
  807. // Retrieve the cookie for the forming node.
  808. //
  809. // Wrap this because all Nodes should be in the database by now.
  810. hr = THR( m_pom->FindObject( CLSID_NodeType,
  811. m_cookieCluster,
  812. bstrName,
  813. IID_NULL,
  814. &m_cookieFormingNode,
  815. &punk // dummy
  816. ) );
  817. Assert( punk == NULL );
  818. if ( FAILED( hr ) )
  819. goto Error;
  820. //
  821. // Set this flag to once a node has been determined to be the
  822. // forming node to keep other nodes from being selected.
  823. //
  824. fDeterminedForming = TRUE;
  825. } // if:
  826. else if ( hr == S_OK ) // node is a member of a cluster
  827. {
  828. //
  829. // Figured out that this node has already formed therefore there
  830. // shouldn't be a "forming node." "Unselect" the forming node by
  831. // releasing the punk and setting it to NULL.
  832. //
  833. if ( m_punkFormingNode != NULL )
  834. {
  835. m_punkFormingNode->Release();
  836. m_punkFormingNode = NULL;
  837. }
  838. //
  839. // Set this flag to once a node has been determined to be the
  840. // forming node to keep other nodes from being selected.
  841. //
  842. fDeterminedForming = TRUE;
  843. } // else:
  844. //
  845. // Create a task to gather this nodes information.
  846. //
  847. hr = THR( m_ptm->CreateTask( TASK_CompareAndPushInformation,
  848. &punk
  849. ) );
  850. if ( FAILED( hr ) )
  851. goto Error;
  852. hr = THR( punk->TypeSafeQI( ITaskCompareAndPushInformation, & ptcapi ) );
  853. punk->Release();
  854. punk = NULL;
  855. if ( FAILED( hr ) )
  856. goto Cleanup;
  857. //
  858. // Set the tasks completion cookie.
  859. //
  860. hr = THR( ptcapi->SetCompletionCookie( m_pcookies[ cNodes ] ) );
  861. if ( FAILED( hr ) )
  862. goto Error;
  863. //
  864. // Tell it what node it is suppose to gather information from.
  865. //
  866. // Find the cookie first!
  867. hr = THR( m_pom->FindObject( CLSID_NodeType,
  868. m_cookieCluster,
  869. bstrName,
  870. IID_NULL,
  871. &cookie,
  872. &punk // dummy
  873. ) );
  874. Assert( punk == NULL );
  875. if ( FAILED( hr ) )
  876. goto Error;
  877. hr = THR( ptcapi->SetNodeCookie( cookie ) );
  878. if ( FAILED( hr ) )
  879. goto Error;
  880. //
  881. // Submit the task.
  882. //
  883. hr = THR( m_ptm->SubmitTask( ptcapi ) );
  884. if ( FAILED( hr ) )
  885. goto Error;
  886. //
  887. // Cleanup for the next node.
  888. //
  889. pccni->Release();
  890. pccni = NULL;
  891. TraceSysFreeString( bstrName );
  892. bstrName = NULL;
  893. ptcapi->Release();
  894. ptcapi = NULL;
  895. } // while: looping thru nodes
  896. Assert( cNodes == m_cNodes );
  897. //
  898. // Now wait for the work to be done.
  899. //
  900. dwErr = -1;
  901. Assert( dwErr != WAIT_OBJECT_0 );
  902. while ( dwErr != WAIT_OBJECT_0 )
  903. {
  904. MSG msg;
  905. while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
  906. {
  907. TranslateMessage( &msg );
  908. DispatchMessage( &msg );
  909. }
  910. dwErr = MsgWaitForMultipleObjectsEx( 1,
  911. &m_event,
  912. INFINITE,
  913. QS_ALLEVENTS | QS_ALLINPUT | QS_ALLPOSTMESSAGE,
  914. 0
  915. );
  916. } // while: dwErr == WAIT_OBJECT_0
  917. //
  918. // Check the status to make sure everyone was happy, if not abort the task.
  919. //
  920. for( cNodes = 0; cNodes < m_cNodes; cNodes ++ )
  921. {
  922. HRESULT hrStatus;
  923. hr = THR( m_pom->GetObject( DFGUID_StandardInfo,
  924. pcookies[ cNodes ],
  925. &punk
  926. ) );
  927. if ( FAILED( hr ) )
  928. goto Error;
  929. hr = THR( punk->TypeSafeQI( IStandardInfo,
  930. &psi
  931. ) );
  932. punk->Release();
  933. punk = NULL;
  934. if ( FAILED( hr ) )
  935. goto Error;
  936. hr = THR( psi->GetStatus( &hrStatus ) );
  937. if ( FAILED( hr ) )
  938. goto Error;
  939. if ( hrStatus != S_OK )
  940. {
  941. hr = hrStatus;
  942. goto Cleanup;
  943. }
  944. }
  945. hr = S_OK;
  946. Cleanup:
  947. Assert( punk == NULL );
  948. if ( pcookies != NULL )
  949. {
  950. for ( cNodes = 0; cNodes < m_cNodes; cNodes++ )
  951. {
  952. if ( pcookies[ cNodes ] != NULL )
  953. {
  954. THR( m_pom->RemoveObject( pcookies[ cNodes ] ) );
  955. }
  956. }
  957. TraceFree( pcookies );
  958. }
  959. TraceSysFreeString( bstrName );
  960. TraceSysFreeString( bstrNotification );
  961. if ( ptcapi != NULL )
  962. {
  963. ptcapi->Release();
  964. }
  965. if ( pcp != NULL )
  966. {
  967. if ( dwCookie != 0 )
  968. {
  969. THR( pcp->Unadvise( dwCookie ) );
  970. }
  971. pcp->Release();
  972. }
  973. if ( pccni != NULL )
  974. {
  975. pccni->Release();
  976. }
  977. if ( psi != NULL )
  978. {
  979. psi->Release();
  980. }
  981. HRETURN( hr );
  982. Error:
  983. //
  984. // Tell the UI layer about the failure.
  985. //
  986. THR( SendStatusReport( NULL,
  987. TASKID_Major_Reanalyze,
  988. TASKID_Minor_Update_Progress, // todo: fill this in
  989. 0,
  990. 0,
  991. 0,
  992. hr,
  993. bstrNotification,
  994. NULL,
  995. NULL
  996. ) );
  997. goto Cleanup;
  998. OutOfMemory:
  999. hr = E_OUTOFMEMORY;
  1000. goto Error;
  1001. } // HrCompareAndPushInformationToNodes()
  1002. //////////////////////////////////////////////////////////////////////////////
  1003. //
  1004. // HRESULT
  1005. // CTaskCommitClusterChanges::HrGatherClusterInformation( void )
  1006. //
  1007. //////////////////////////////////////////////////////////////////////////////
  1008. HRESULT
  1009. CTaskCommitClusterChanges::HrGatherClusterInformation( void )
  1010. {
  1011. TraceFunc( "" );
  1012. HRESULT hr;
  1013. BSTR bstrNotification = NULL;
  1014. IUnknown * punk = NULL;
  1015. IClusCfgClusterInfo * pccci = NULL;
  1016. IClusCfgCredentials * piccc = NULL;
  1017. IClusCfgNetworkInfo * pccni = NULL;
  1018. //
  1019. // Ask the object manager for the cluster configuration object.
  1020. //
  1021. hr = THR( m_pom->GetObject( DFGUID_ClusterConfigurationInfo, m_cookieCluster, &punk ) );
  1022. if ( FAILED( hr ) )
  1023. goto Error;
  1024. hr = THR( punk->TypeSafeQI( IClusCfgClusterInfo, &pccci ) );
  1025. if ( FAILED( hr ) )
  1026. goto Error;
  1027. //
  1028. // Gather common properties.
  1029. //
  1030. hr = THR( pccci->GetName( &m_bstrClusterName ) );
  1031. if ( FAILED( hr ) )
  1032. goto Error;
  1033. TraceMemoryAddBSTR( m_bstrClusterName );
  1034. hr = STHR( pccci->GetBindingString( &m_bstrClusterBindingString ) );
  1035. if ( FAILED( hr ) )
  1036. {
  1037. goto Error;
  1038. } // if:
  1039. TraceMemoryAddBSTR( m_bstrClusterBindingString );
  1040. LogMsg( L"[MT] Cluster binding string is {%ws}.", m_bstrClusterBindingString );
  1041. hr = THR( pccci->GetClusterServiceAccountCredentials( &piccc ) );
  1042. if ( FAILED( hr ) )
  1043. goto Error;
  1044. hr = THR( piccc->GetCredentials( &m_bstrAccountName, &m_bstrAccountDomain, &m_bstrAccountPassword ) );
  1045. if ( FAILED( hr ) )
  1046. goto Error;
  1047. hr = THR( pccci->GetIPAddress( &m_ulIPAddress ) );
  1048. if ( FAILED( hr ) )
  1049. goto Error;
  1050. hr = THR( pccci->GetSubnetMask( &m_ulSubnetMask ) );
  1051. if ( FAILED( hr ) )
  1052. goto Error;
  1053. hr = THR( pccci->GetNetworkInfo( &pccni ) );
  1054. if ( FAILED( hr ) )
  1055. goto Error;
  1056. hr = THR( pccni->GetUID( &m_bstrNetworkUID ) );
  1057. if ( FAILED( hr ) )
  1058. goto Error;
  1059. TraceMemoryAddBSTR( m_bstrNetworkUID );
  1060. Cleanup:
  1061. TraceSysFreeString( bstrNotification );
  1062. if ( punk != NULL )
  1063. {
  1064. punk->Release();
  1065. }
  1066. if ( pccni != NULL )
  1067. {
  1068. pccni->Release();
  1069. }
  1070. if ( piccc != NULL )
  1071. {
  1072. piccc->Release();
  1073. }
  1074. if ( pccci != NULL )
  1075. {
  1076. pccci->Release();
  1077. }
  1078. HRETURN( hr );
  1079. Error:
  1080. //
  1081. // Tell the UI layer about the failure.
  1082. //
  1083. THR( HrLoadStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_INCONSISTANT_MIDDLETIER_DATABASE, &bstrNotification ) );
  1084. THR( SendStatusReport( NULL,
  1085. TASKID_Major_Reanalyze,
  1086. TASKID_Minor_Inconsistant_MiddleTier_Database,
  1087. 0,
  1088. 0,
  1089. 0,
  1090. hr,
  1091. bstrNotification,
  1092. NULL,
  1093. NULL
  1094. ) );
  1095. goto Cleanup;
  1096. } // HrGatherClusterInformation()
  1097. //////////////////////////////////////////////////////////////////////////////
  1098. //
  1099. // HRESULT
  1100. // CTaskCommitClusterChanges::HrFormFirstNode( void )
  1101. //
  1102. //////////////////////////////////////////////////////////////////////////////
  1103. HRESULT
  1104. CTaskCommitClusterChanges::HrFormFirstNode( void )
  1105. {
  1106. TraceFunc( "" );
  1107. HRESULT hr;
  1108. ULONG celtDummy;
  1109. BSTR bstrName = NULL;
  1110. BSTR bstrNotification = NULL;
  1111. BSTR bstrUID = NULL;
  1112. IUnknown * punk = NULL;
  1113. IClusCfgCredentials * piccc = NULL;
  1114. IClusCfgNodeInfo * pccni = NULL;
  1115. IClusCfgClusterInfo * pccci = NULL;
  1116. IClusCfgServer * pccs = NULL;
  1117. IEnumClusCfgNetworks * peccn = NULL;
  1118. IClusCfgNetworkInfo * pccneti = NULL;
  1119. //
  1120. // TODO: gpease 25-MAR-2000
  1121. // Figure out what additional work to do here.
  1122. //
  1123. //
  1124. // Get the name of the node.
  1125. //
  1126. hr = THR( m_pom->GetObject( DFGUID_NodeInformation,
  1127. m_cookieFormingNode,
  1128. &punk
  1129. ) );
  1130. if ( FAILED( hr ) )
  1131. goto Cleanup;
  1132. hr = THR( punk->TypeSafeQI( IClusCfgNodeInfo, &pccni ) );
  1133. if ( FAILED( hr ) )
  1134. goto Cleanup;
  1135. punk->Release();
  1136. punk = NULL;
  1137. hr = THR( pccni->GetName( &bstrName ) );
  1138. if ( FAILED( hr ) )
  1139. goto Cleanup;
  1140. TraceMemoryAddBSTR( bstrName );
  1141. //
  1142. // Create notification string.
  1143. //
  1144. hr = THR( HrLoadStringIntoBSTR( g_hInstance,
  1145. IDS_TASKID_MINOR_FORMING_NODE,
  1146. &bstrNotification
  1147. ) );
  1148. if ( FAILED( hr ) )
  1149. goto Error;
  1150. //
  1151. // Update the UI layer telling it that we are about to start.
  1152. //
  1153. hr = THR( SendStatusReport( bstrName,
  1154. TASKID_Major_Configure_Cluster_Services,
  1155. TASKID_Minor_Forming_Node,
  1156. 0,
  1157. 2,
  1158. 0,
  1159. S_OK,
  1160. bstrNotification,
  1161. NULL,
  1162. NULL
  1163. ) );
  1164. if ( FAILED( hr ) )
  1165. goto Cleanup;
  1166. //
  1167. // Ask the Connection Manager for a connection to the node.
  1168. //
  1169. hr = THR( m_pcm->GetConnectionToObject( m_cookieFormingNode, &punk ) );
  1170. if ( FAILED( hr ) )
  1171. goto Error;
  1172. hr = THR( punk->TypeSafeQI( IClusCfgServer, &pccs ) );
  1173. if ( FAILED( hr ) )
  1174. goto Error;
  1175. punk->Release();
  1176. punk = NULL;
  1177. //
  1178. // Get the node info interface.
  1179. //
  1180. hr = THR( pccs->GetClusterNodeInfo( &pccni ) );
  1181. if ( FAILED( hr ) )
  1182. goto Error;
  1183. //
  1184. // Retrieve the server's Cluster Configuration Object..
  1185. //
  1186. hr = THR( pccni->GetClusterConfigInfo( &pccci ) );
  1187. if ( FAILED( hr ) )
  1188. goto Error;
  1189. //
  1190. // Put the properties into the remoted object.
  1191. //
  1192. hr = THR( pccci->SetName( m_bstrClusterName ) );
  1193. if ( FAILED( hr ) )
  1194. goto Error;
  1195. hr = STHR( pccci->SetBindingString( m_bstrClusterBindingString ) );
  1196. if ( FAILED( hr ) )
  1197. goto Error;
  1198. hr = THR( pccci->GetClusterServiceAccountCredentials( &piccc ) );
  1199. if ( FAILED( hr ) )
  1200. goto Error;
  1201. hr = THR( piccc->SetCredentials( m_bstrAccountName, m_bstrAccountDomain, m_bstrAccountPassword ) );
  1202. if( FAILED( hr ) )
  1203. goto Error;
  1204. hr = THR( pccci->SetIPAddress( m_ulIPAddress ) );
  1205. if ( FAILED( hr ) )
  1206. goto Error;
  1207. hr = THR( pccci->SetSubnetMask( m_ulSubnetMask ) );
  1208. if ( FAILED( hr ) )
  1209. goto Error;
  1210. //
  1211. // Find the network that matches the UID of network to host the
  1212. // IP address.
  1213. //
  1214. hr = THR( pccs->GetNetworksEnum( &peccn ) );
  1215. if ( FAILED( hr ) )
  1216. goto Error;
  1217. Assert( hr == S_OK );
  1218. while ( hr == S_OK )
  1219. {
  1220. hr = STHR( peccn->Next( 1, &pccneti, &celtDummy ) );
  1221. if ( hr == S_FALSE )
  1222. {
  1223. //
  1224. // Somehow, there isn't a network that matches the UID of the
  1225. // network. How did we get this far?
  1226. //
  1227. hr = THR( E_UNEXPECTED );
  1228. goto Error;
  1229. }
  1230. if ( FAILED( hr ) )
  1231. goto Error;
  1232. hr = THR( pccneti->GetUID( &bstrUID ) );
  1233. if ( FAILED( hr ) )
  1234. goto Error;
  1235. TraceMemoryAddBSTR( bstrUID );
  1236. if ( wcscmp( bstrUID, m_bstrNetworkUID ) == 0 )
  1237. {
  1238. //
  1239. // Found the network!
  1240. //
  1241. break;
  1242. }
  1243. TraceSysFreeString( bstrUID );
  1244. bstrUID = NULL;
  1245. pccneti->Release();
  1246. pccneti = NULL;
  1247. } // while: hr == S_OK
  1248. hr = THR( pccci->SetNetworkInfo( pccneti ) );
  1249. if ( FAILED( hr ) )
  1250. goto Error;
  1251. //
  1252. // Configure that node to create a cluster
  1253. //
  1254. hr = THR( pccci->SetCommitMode( cmCREATE_CLUSTER ) );
  1255. if ( FAILED( hr ) )
  1256. goto Error;
  1257. //
  1258. // Update the UI layer telling it that we are making progress.
  1259. //
  1260. hr = THR( SendStatusReport( bstrName,
  1261. TASKID_Major_Configure_Cluster_Services,
  1262. TASKID_Minor_Forming_Node,
  1263. 0,
  1264. 2,
  1265. 1,
  1266. hr,
  1267. NULL, // don't need to update string
  1268. NULL,
  1269. NULL
  1270. ) );
  1271. if ( FAILED( hr ) )
  1272. goto Cleanup;
  1273. //
  1274. // Commit this node!
  1275. //
  1276. hr = THR( pccs->CommitChanges() );
  1277. if ( FAILED( hr ) )
  1278. goto Error;
  1279. Cleanup:
  1280. if ( punk != NULL )
  1281. {
  1282. punk->Release();
  1283. }
  1284. TraceSysFreeString( bstrName );
  1285. TraceSysFreeString( bstrNotification );
  1286. if ( pccneti != NULL )
  1287. {
  1288. pccneti->Release();
  1289. }
  1290. if ( peccn != NULL )
  1291. {
  1292. peccn->Release();
  1293. }
  1294. if ( piccc != NULL )
  1295. {
  1296. piccc->Release();
  1297. }
  1298. if ( pccni != NULL )
  1299. {
  1300. pccni->Release();
  1301. }
  1302. if ( pccci != NULL )
  1303. {
  1304. pccci->Release();
  1305. }
  1306. if ( pccs != NULL )
  1307. {
  1308. pccs->Release();
  1309. }
  1310. HRETURN( hr );
  1311. Error:
  1312. //
  1313. // Tell the UI layer about the failure.
  1314. //
  1315. THR( SendStatusReport( bstrName,
  1316. TASKID_Major_Configure_Cluster_Services,
  1317. TASKID_Minor_Forming_Node,
  1318. 0,
  1319. 2,
  1320. 2,
  1321. hr,
  1322. NULL, // don't need to update string
  1323. NULL,
  1324. NULL
  1325. ) );
  1326. goto Cleanup;
  1327. } // HrFormFirstNode()
  1328. //////////////////////////////////////////////////////////////////////////////
  1329. //
  1330. // HRESULT
  1331. // CTaskCommitClusterChanges::HrAddJoiningNodes( void )
  1332. //
  1333. //////////////////////////////////////////////////////////////////////////////
  1334. HRESULT
  1335. CTaskCommitClusterChanges::HrAddJoiningNodes( void )
  1336. {
  1337. TraceFunc( "" );
  1338. HRESULT hr;
  1339. ULONG cNodes;
  1340. ULONG celtDummy;
  1341. OBJECTCOOKIE cookie;
  1342. BSTR bstrName = NULL;
  1343. IClusCfgNodeInfo * pccni = NULL;
  1344. //
  1345. // Reset the enum to use again.
  1346. //
  1347. hr = THR( m_pen->Reset() );
  1348. if ( FAILED( hr ) )
  1349. goto Cleanup;
  1350. //
  1351. // Loop thru the nodes, adding all joining nodes, skipping the forming node (if any).
  1352. //
  1353. Assert( hr == S_OK );
  1354. for( cNodes = 0; hr == S_OK; cNodes ++ )
  1355. {
  1356. IUnknown * punk;
  1357. //
  1358. // Cleanup
  1359. //
  1360. TraceSysFreeString( bstrName );
  1361. bstrName = NULL;
  1362. //
  1363. // Grab the next node.
  1364. //
  1365. hr = STHR( m_pen->Next( 1, &pccni, &celtDummy ) );
  1366. if ( hr == S_FALSE )
  1367. break;
  1368. if ( FAILED( hr ) )
  1369. goto Error;
  1370. //
  1371. // Check to see if this is the forming node.
  1372. //
  1373. hr = THR( pccni->TypeSafeQI( IUnknown, &punk ) );
  1374. if ( FAILED( hr ) )
  1375. goto Error;
  1376. punk->Release(); // release promptly.
  1377. //
  1378. // Get the name.
  1379. //
  1380. Assert( bstrName == NULL );
  1381. hr = THR( pccni->GetName( &bstrName ) );
  1382. if ( FAILED( hr ) )
  1383. goto Error;
  1384. TraceMemoryAddBSTR( bstrName );
  1385. //
  1386. // Check cluster membership.
  1387. //
  1388. hr = STHR( pccni->IsMemberOfCluster() );
  1389. if ( FAILED( hr ) )
  1390. goto Error;
  1391. pccni->Release();
  1392. pccni = NULL;
  1393. if ( hr == S_OK )
  1394. continue; // already clustered - skip it.
  1395. //
  1396. // KB: We only need the punk's address to see if the objects are the
  1397. // same COM object by comparing the IUnknown interfaces.
  1398. //
  1399. if ( m_punkFormingNode == punk )
  1400. continue; // skip it - we already "formed" above
  1401. //
  1402. // Find the node's cookie.
  1403. //
  1404. // This should be already cache! E_PENDING is not a good answer!
  1405. hr = THR( m_pom->FindObject( CLSID_NodeType,
  1406. m_cookieCluster,
  1407. bstrName,
  1408. IID_NULL,
  1409. &cookie,
  1410. &punk // dummy
  1411. ) );
  1412. Assert( punk == NULL );
  1413. if ( FAILED( hr ) )
  1414. goto Error;
  1415. //
  1416. // Add the node to the cluster.
  1417. //
  1418. hr = THR( HrAddAJoiningNode( bstrName, cookie ) );
  1419. if ( FAILED( hr ) )
  1420. goto Cleanup;
  1421. } // while: looping thru nodes a second time.
  1422. Assert( cNodes == m_cNodes );
  1423. hr = S_OK;
  1424. Cleanup:
  1425. TraceSysFreeString( bstrName );
  1426. if ( pccni != NULL )
  1427. {
  1428. pccni->Release();
  1429. }
  1430. HRETURN( hr );
  1431. Error:
  1432. THR( SendStatusReport( bstrName,
  1433. TASKID_Major_Configure_Cluster_Services,
  1434. TASKID_Minor_Joining_Node,
  1435. 0,
  1436. 2,
  1437. 2,
  1438. hr,
  1439. NULL,
  1440. NULL,
  1441. NULL
  1442. ) );
  1443. goto Cleanup;
  1444. } // HrAddJoiningNodes()
  1445. //////////////////////////////////////////////////////////////////////////////
  1446. //
  1447. // HRESULT
  1448. // CTaskCommitClusterChanges::HrAddAJoiningNode(
  1449. // BSTR bstrNameIn,
  1450. // OBJECTCOOKIE cookieIn
  1451. // )
  1452. //
  1453. //////////////////////////////////////////////////////////////////////////////
  1454. HRESULT
  1455. CTaskCommitClusterChanges::HrAddAJoiningNode(
  1456. BSTR bstrNameIn,
  1457. OBJECTCOOKIE cookieIn
  1458. )
  1459. {
  1460. TraceFunc( "" );
  1461. HRESULT hr;
  1462. ULONG cNodes;
  1463. OBJECTCOOKIE cookie;
  1464. BSTR bstrNotification = NULL;
  1465. IUnknown * punk = NULL;
  1466. IClusCfgCredentials * piccc = NULL;
  1467. IClusCfgNodeInfo * pccni = NULL;
  1468. IClusCfgClusterInfo * pccci = NULL;
  1469. IClusCfgServer * pccs = NULL;
  1470. //
  1471. // Create the notification string
  1472. //
  1473. hr = THR( HrLoadStringIntoBSTR( g_hInstance,
  1474. IDS_TASKID_MINOR_JOINING_NODE,
  1475. &bstrNotification
  1476. ) );
  1477. if ( FAILED( hr ) )
  1478. goto Error;
  1479. //
  1480. // Tell UI layer we are about to start this.
  1481. //
  1482. hr = THR( SendStatusReport( bstrNameIn,
  1483. TASKID_Major_Configure_Cluster_Services,
  1484. TASKID_Minor_Joining_Node,
  1485. 0,
  1486. 2,
  1487. 0,
  1488. S_OK,
  1489. bstrNotification,
  1490. NULL,
  1491. NULL
  1492. ) );
  1493. if ( FAILED( hr ) )
  1494. goto Cleanup;
  1495. //
  1496. // Connect to the node.
  1497. //
  1498. hr = THR( m_pcm->GetConnectionToObject( cookieIn,
  1499. &punk
  1500. ) );
  1501. if ( FAILED( hr ) )
  1502. goto Error;
  1503. hr = THR( punk->TypeSafeQI( IClusCfgServer, &pccs ) );
  1504. if ( FAILED( hr ) )
  1505. goto Error;
  1506. //
  1507. // Get the node info interface.
  1508. //
  1509. hr = THR( pccs->GetClusterNodeInfo( &pccni ) );
  1510. if ( FAILED( hr ) )
  1511. goto Error;
  1512. //
  1513. // Retrieve the server's Cluster Configuration Object..
  1514. //
  1515. hr = THR( pccni->GetClusterConfigInfo( &pccci ) );
  1516. if ( FAILED( hr ) )
  1517. goto Error;
  1518. //
  1519. // Put the properties into the remoted object.
  1520. //
  1521. hr = THR( pccci->SetName( m_bstrClusterName ) );
  1522. if ( FAILED( hr ) )
  1523. goto Error;
  1524. hr = THR( pccci->SetBindingString( m_bstrClusterBindingString ) );
  1525. if ( FAILED( hr ) )
  1526. goto Error;
  1527. hr = THR( pccci->GetClusterServiceAccountCredentials( &piccc ) );
  1528. if ( FAILED( hr ) )
  1529. goto Error;
  1530. hr = THR( piccc->SetCredentials( m_bstrAccountName, m_bstrAccountDomain, m_bstrAccountPassword ) );
  1531. if ( FAILED( hr ) )
  1532. goto Error;
  1533. hr = THR( pccci->SetIPAddress( m_ulIPAddress ) );
  1534. if ( FAILED( hr ) )
  1535. goto Error;
  1536. hr = THR( pccci->SetSubnetMask( m_ulSubnetMask ) );
  1537. if ( FAILED( hr ) )
  1538. goto Error;
  1539. //
  1540. // Set this node to add itself to a cluster
  1541. //
  1542. hr = THR( pccci->SetCommitMode( cmADD_NODE_TO_CLUSTER ) );
  1543. if ( FAILED( hr ) )
  1544. goto Error;
  1545. //
  1546. // Tell the UI layer we are making progess.... the server will then send messages
  1547. // indicating what it is doing.
  1548. //
  1549. hr = THR( SendStatusReport( bstrNameIn,
  1550. TASKID_Major_Configure_Cluster_Services,
  1551. TASKID_Minor_Joining_Node,
  1552. 0,
  1553. 2,
  1554. 1,
  1555. S_OK,
  1556. NULL, // don't need to update string
  1557. NULL,
  1558. NULL
  1559. ) );
  1560. if ( FAILED( hr ) )
  1561. goto Error;
  1562. //
  1563. // Commit this node!
  1564. //
  1565. hr = THR( pccs->CommitChanges() );
  1566. if ( FAILED( hr ) )
  1567. goto Error;
  1568. Cleanup:
  1569. if ( punk != NULL )
  1570. {
  1571. punk->Release();
  1572. }
  1573. TraceSysFreeString( bstrNotification );
  1574. if ( piccc != NULL )
  1575. {
  1576. piccc->Release();
  1577. }
  1578. if ( pccci != NULL )
  1579. {
  1580. pccci->Release();
  1581. }
  1582. if ( pccs != NULL )
  1583. {
  1584. pccs->Release();
  1585. }
  1586. if ( pccni != NULL )
  1587. {
  1588. pccni->Release();
  1589. }
  1590. HRETURN( hr );
  1591. Error:
  1592. THR( SendStatusReport( bstrNameIn,
  1593. TASKID_Major_Configure_Cluster_Services,
  1594. TASKID_Minor_Joining_Node,
  1595. 0,
  1596. 2,
  1597. 1,
  1598. hr,
  1599. NULL, // don't need to update string
  1600. NULL,
  1601. NULL
  1602. ) );
  1603. goto Cleanup;
  1604. } // HrAddAJoiningNode()