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.

2346 lines
75 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // TaskGatherInformation.cpp
  7. //
  8. // Description:
  9. // CTaskGatherInformation implementation.
  10. //
  11. // Maintained By:
  12. // Galen Barbee (GalenB) 02-FEB-2000
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. #include "Pch.h"
  16. #include <StatusReports.h>
  17. #include "TaskGatherInformation.h"
  18. #include "ManagedResource.h"
  19. #include "ManagedNetwork.h"
  20. DEFINE_THISCLASS("CTaskGatherInformation")
  21. //
  22. // Failure code.
  23. //
  24. #define SSR_TGI_FAILED( _major, _minor, _hr ) \
  25. { \
  26. HRESULT __hrTemp; \
  27. __hrTemp = THR( HrSendStatusReport( m_bstrNodeName, _major, _minor, 1, 1, 1, _hr, IDS_ERR_TGI_FAILED_TRY_TO_REANALYZE, 0 ) ); \
  28. if ( FAILED( __hrTemp ) && SUCCEEDED( _hr ) )\
  29. { \
  30. _hr = __hrTemp; \
  31. } \
  32. }
  33. //////////////////////////////////////////////////////////////////////////////
  34. //
  35. // Static function prototypes
  36. //
  37. //////////////////////////////////////////////////////////////////////////////
  38. static
  39. HRESULT
  40. HrTotalManagedResourceCount(
  41. IEnumClusCfgManagedResources * pResourceEnumIn
  42. , IEnumClusCfgNetworks * pNetworkEnumIn
  43. , DWORD * pnCountOut
  44. );
  45. //****************************************************************************
  46. //
  47. // Constructor / Destructor
  48. //
  49. //****************************************************************************
  50. //////////////////////////////////////////////////////////////////////////////
  51. //
  52. // HRESULT
  53. // CTaskGatherInformation::S_HrCreateInstance(
  54. // IUnknown ** punkOut
  55. // )
  56. //
  57. //////////////////////////////////////////////////////////////////////////////
  58. HRESULT
  59. CTaskGatherInformation::S_HrCreateInstance(
  60. IUnknown ** ppunkOut
  61. )
  62. {
  63. TraceFunc( "" );
  64. HRESULT hr = S_OK;
  65. CTaskGatherInformation * ptgi = NULL;
  66. Assert( ppunkOut != NULL );
  67. if ( ppunkOut == NULL )
  68. {
  69. hr = THR( E_POINTER );
  70. goto Cleanup;
  71. }
  72. ptgi = new CTaskGatherInformation;
  73. if ( ptgi == NULL )
  74. {
  75. hr = THR( E_OUTOFMEMORY );
  76. goto Cleanup;
  77. }
  78. hr = THR( ptgi->HrInit() );
  79. if ( FAILED( hr ) )
  80. {
  81. goto Cleanup;
  82. }
  83. hr = THR( ptgi->TypeSafeQI( IUnknown, ppunkOut ) );
  84. if ( FAILED( hr ) )
  85. {
  86. goto Cleanup;
  87. }
  88. TraceMoveToMemoryList( *ppunkOut, g_GlobalMemoryList );
  89. Cleanup:
  90. if ( ptgi != NULL )
  91. {
  92. ptgi->Release();
  93. }
  94. HRETURN( hr );
  95. } //*** CTaskGatherInformation::S_HrCreateInstance
  96. //////////////////////////////////////////////////////////////////////////////
  97. //
  98. // CTaskGatherInformation::CTaskGatherInformation
  99. //
  100. //////////////////////////////////////////////////////////////////////////////
  101. CTaskGatherInformation::CTaskGatherInformation( void )
  102. : m_cRef( 1 )
  103. {
  104. TraceFunc( "" );
  105. InterlockedIncrement( &g_cObjects );
  106. TraceFuncExit();
  107. } //*** CTaskGatherInformation::CTaskGatherInformation
  108. //////////////////////////////////////////////////////////////////////////////
  109. //
  110. // STDMETHODIMP
  111. // CTaskGatherInformation::HrInit( void )
  112. //
  113. //////////////////////////////////////////////////////////////////////////////
  114. STDMETHODIMP
  115. CTaskGatherInformation::HrInit( void )
  116. {
  117. TraceFunc( "" );
  118. HRESULT hr = S_OK;
  119. // IUnknown stuff
  120. Assert( m_cRef == 1 );
  121. // IDoTask / ITaskGatherInformation
  122. Assert( m_cookieCompletion == NULL );
  123. Assert( m_cookieNode == NULL );
  124. Assert( m_pcccb == NULL );
  125. Assert( m_fAdding == FALSE );
  126. Assert( m_cResources == 0 );
  127. Assert( m_pom == NULL );
  128. Assert( m_pccs == NULL );
  129. Assert( m_bstrNodeName == NULL );
  130. Assert( m_ulQuorumDiskSize == 0 );
  131. Assert( m_pccmriQuorum == NULL );
  132. Assert( m_fStop == FALSE );
  133. Assert( m_fMinConfig == FALSE );
  134. HRETURN( hr );
  135. } //*** CTaskGatherInformation::HrInit
  136. //////////////////////////////////////////////////////////////////////////////
  137. //
  138. // CTaskGatherInformation::~CTaskGatherInformation
  139. //
  140. //////////////////////////////////////////////////////////////////////////////
  141. CTaskGatherInformation::~CTaskGatherInformation( void )
  142. {
  143. TraceFunc( "" );
  144. if ( m_pcccb != NULL )
  145. {
  146. m_pcccb->Release();
  147. }
  148. if ( m_pom != NULL )
  149. {
  150. m_pom->Release();
  151. }
  152. if ( m_pccs != NULL )
  153. {
  154. m_pccs->Release();
  155. }
  156. TraceSysFreeString( m_bstrNodeName );
  157. InterlockedDecrement( &g_cObjects );
  158. TraceFuncExit();
  159. } //*** CTaskGatherInformation::~CTaskGatherInformation
  160. //****************************************************************************
  161. //
  162. // IUnknown
  163. //
  164. //****************************************************************************
  165. //////////////////////////////////////////////////////////////////////////////
  166. //++
  167. //
  168. // CTaskGatherInformation::QueryInterface
  169. //
  170. // Description:
  171. // Query this object for the passed in interface.
  172. //
  173. // Arguments:
  174. // riidIn
  175. // Id of interface requested.
  176. //
  177. // ppvOut
  178. // Pointer to the requested interface.
  179. //
  180. // Return Value:
  181. // S_OK
  182. // If the interface is available on this object.
  183. //
  184. // E_NOINTERFACE
  185. // If the interface is not available.
  186. //
  187. // E_POINTER
  188. // ppvOut was NULL.
  189. //
  190. // Remarks:
  191. // None.
  192. //
  193. //--
  194. //////////////////////////////////////////////////////////////////////////////
  195. STDMETHODIMP
  196. CTaskGatherInformation::QueryInterface(
  197. REFIID riidIn
  198. , LPVOID * ppvOut
  199. )
  200. {
  201. TraceQIFunc( riidIn, ppvOut );
  202. HRESULT hr = S_OK;
  203. //
  204. // Validate arguments.
  205. //
  206. Assert( ppvOut != NULL );
  207. if ( ppvOut == NULL )
  208. {
  209. hr = THR( E_POINTER );
  210. goto Cleanup;
  211. }
  212. //
  213. // Handle known interfaces.
  214. //
  215. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  216. {
  217. *ppvOut = static_cast< ITaskGatherInformation * >( this );
  218. } // if: IUnknown
  219. else if ( IsEqualIID( riidIn, IID_ITaskGatherInformation ) )
  220. {
  221. *ppvOut = TraceInterface( __THISCLASS__, ITaskGatherInformation, this, 0 );
  222. } // else if: ITaskGatherInformation
  223. else if ( IsEqualIID( riidIn, IID_IDoTask ) )
  224. {
  225. *ppvOut = TraceInterface( __THISCLASS__, IDoTask, this, 0 );
  226. } // else if: IDoTask
  227. else
  228. {
  229. *ppvOut = NULL;
  230. hr = E_NOINTERFACE;
  231. }
  232. //
  233. // Add a reference to the interface if successful.
  234. //
  235. if ( SUCCEEDED( hr ) )
  236. {
  237. ((IUnknown *) *ppvOut)->AddRef();
  238. } // if: success
  239. Cleanup:
  240. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  241. } //*** CTaskGatherInformation::QueryInterface
  242. //////////////////////////////////////////////////////////////////////////////
  243. //
  244. // STDMETHODIMP_( ULONG )
  245. // CTaskGatherInformation::AddRef
  246. //
  247. //////////////////////////////////////////////////////////////////////////////
  248. STDMETHODIMP_( ULONG )
  249. CTaskGatherInformation::AddRef( void )
  250. {
  251. TraceFunc( "[IUnknown]" );
  252. InterlockedIncrement( &m_cRef );
  253. CRETURN( m_cRef );
  254. } //*** CTaskGatherInformation::AddRef
  255. //////////////////////////////////////////////////////////////////////////////
  256. //
  257. // STDMETHODIMP_( ULONG )
  258. // CTaskGatherInformation::Release
  259. //
  260. //////////////////////////////////////////////////////////////////////////////
  261. STDMETHODIMP_( ULONG )
  262. CTaskGatherInformation::Release( void )
  263. {
  264. TraceFunc( "[IUnknown]" );
  265. LONG cRef;
  266. cRef = InterlockedDecrement( &m_cRef );
  267. if ( cRef == 0 )
  268. {
  269. TraceDo( delete this );
  270. }
  271. CRETURN( cRef );
  272. } //*** CTaskGatherInformation::Release
  273. //****************************************************************************
  274. //
  275. // ITaskGatherInformation
  276. //
  277. //****************************************************************************
  278. //////////////////////////////////////////////////////////////////////////////
  279. //
  280. // STDMETHODIMP
  281. // CTaskGatherInformation::BeginTask( void )
  282. //
  283. //////////////////////////////////////////////////////////////////////////////
  284. STDMETHODIMP
  285. CTaskGatherInformation::BeginTask( void )
  286. {
  287. TraceFunc( "[IDoTask]" );
  288. HRESULT hr;
  289. IServiceProvider * psp = NULL;
  290. IUnknown * punk = NULL;
  291. IConnectionPointContainer * pcpc = NULL;
  292. IConnectionPoint * pcp = NULL;
  293. INotifyUI * pnui = NULL;
  294. IConnectionManager * pcm = NULL;
  295. IStandardInfo * psi = NULL;
  296. IClusCfgCapabilities * pccc = NULL;
  297. IEnumClusCfgManagedResources * peccmr = NULL;
  298. IEnumClusCfgNetworks * pen = NULL;
  299. DWORD cTotalResources = 0;
  300. TraceInitializeThread( L"TaskGatherInformation" );
  301. //
  302. // Make sure we weren't "reused"
  303. //
  304. Assert( m_cResources == 0 );
  305. //
  306. // Gather the manager we need to complete our tasks.
  307. //
  308. hr = THR( CoCreateInstance( CLSID_ServiceManager,
  309. NULL,
  310. CLSCTX_INPROC_SERVER,
  311. TypeSafeParams( IServiceProvider, &psp )
  312. ) );
  313. if ( FAILED( hr ) )
  314. {
  315. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_CoCreate_ServiceManager, hr );
  316. goto Cleanup;
  317. }
  318. hr = THR( psp->TypeSafeQS( CLSID_ObjectManager, IObjectManager, &m_pom ) );
  319. if ( FAILED( hr ) )
  320. {
  321. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_QS_ObjectManager, hr );
  322. goto Cleanup;
  323. }
  324. hr = THR( psp->TypeSafeQS( CLSID_NotificationManager, IConnectionPointContainer, &pcpc ) );
  325. if ( FAILED( hr ) )
  326. {
  327. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_QS_NotificationManager, hr );
  328. goto Cleanup;
  329. }
  330. hr = THR( pcpc->FindConnectionPoint( IID_INotifyUI, &pcp ) );
  331. if ( FAILED( hr ) )
  332. {
  333. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_FindConnectionPoint, hr );
  334. goto Cleanup;
  335. }
  336. pcp = TraceInterface( L"CTaskGatherInformation!IConnectionPoint", IConnectionPoint, pcp, 1 );
  337. hr = THR( pcp->TypeSafeQI( INotifyUI, &pnui ) );
  338. if ( FAILED( hr ) )
  339. {
  340. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_QI_pnui, hr );
  341. goto Cleanup;
  342. }
  343. pnui = TraceInterface( L"CTaskGatherInformation!INotifyUI", INotifyUI, pnui, 1 );
  344. hr = THR( psp->TypeSafeQS( CLSID_ClusterConnectionManager, IConnectionManager, &pcm ) );
  345. if ( FAILED( hr ) )
  346. {
  347. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_QS_ClusterConnectionManager, hr );
  348. goto Cleanup;
  349. }
  350. // release promptly
  351. psp->Release();
  352. psp = NULL;
  353. if ( m_fStop == TRUE )
  354. {
  355. goto Cleanup;
  356. } // if:
  357. //
  358. // Ask the object manager for the name of the node.
  359. //
  360. hr = THR( m_pom->GetObject( DFGUID_StandardInfo, m_cookieNode, &punk ) );
  361. if ( FAILED( hr ) )
  362. {
  363. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_GetObject_StandardInfo, hr );
  364. goto Cleanup;
  365. }
  366. hr = THR( punk->TypeSafeQI( IStandardInfo, &psi ) );
  367. if ( FAILED( hr ) )
  368. {
  369. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_GetObject_StandardInfo_QI, hr );
  370. goto Cleanup;
  371. }
  372. psi = TraceInterface( L"TaskGatherInformation!IStandardInfo", IStandardInfo, psi, 1 );
  373. punk->Release();
  374. punk = NULL;
  375. hr = THR( psi->GetName( &m_bstrNodeName ) );
  376. if ( FAILED( hr ) )
  377. {
  378. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_GetName, hr );
  379. goto Cleanup;
  380. }
  381. TraceMemoryAddBSTR( m_bstrNodeName );
  382. //
  383. // Create progress message and tell the UI layer our progress
  384. // for checking the node's cluster feasibility.
  385. //
  386. hr = THR( HrSendStatusReport(
  387. m_bstrNodeName
  388. , TASKID_Major_Check_Node_Feasibility
  389. , TASKID_Minor_Checking_Node_Cluster_Feasibility
  390. , 0
  391. , 2
  392. , 0
  393. , S_OK
  394. , IDS_TASKID_MINOR_CHECKING_NODE_CLUSTER_FEASIBILITY
  395. , 0
  396. ) );
  397. if ( FAILED( hr ) )
  398. {
  399. goto ClusterFeasibilityError;
  400. }
  401. if ( m_fStop == TRUE )
  402. {
  403. goto Cleanup;
  404. } // if:
  405. //
  406. // Ask the connection manager for a connection to the node.
  407. //
  408. hr = THRE( pcm->GetConnectionToObject( m_cookieNode, &punk ), HR_S_RPC_S_CLUSTER_NODE_DOWN );
  409. if ( hr != S_OK )
  410. {
  411. THR( HrSendStatusReport(
  412. m_bstrNodeName
  413. , TASKID_Major_Check_Node_Feasibility
  414. , TASKID_Minor_Checking_Node_Cluster_Feasibility
  415. , 0
  416. , 2
  417. , 2
  418. , hr
  419. , IDS_TASKID_MINOR_FAILED_TO_CONNECT_TO_NODE
  420. , 0
  421. ) );
  422. // don't care about error from here - we are returning an error.
  423. //
  424. // If we failed to get a connection to the node, we delete the
  425. // node from the configuration.
  426. //
  427. THR( m_pom->RemoveObject( m_cookieNode ) );
  428. // don't care if there is an error because we can't fix it!
  429. goto ClusterFeasibilityError;
  430. }
  431. hr = THR( punk->TypeSafeQI( IClusCfgServer, &m_pccs ) );
  432. if ( FAILED( hr ) )
  433. {
  434. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_GetConnectionToObject_QI_m_pccs, hr );
  435. goto ClusterFeasibilityError;
  436. }
  437. punk->Release();
  438. punk = NULL;
  439. //
  440. // Tell the UI layer we're done connecting to the node.
  441. //
  442. hr = THR( SendStatusReport( m_bstrNodeName,
  443. TASKID_Major_Check_Node_Feasibility,
  444. TASKID_Minor_Checking_Node_Cluster_Feasibility,
  445. 0, // min
  446. 2, // max
  447. 1, // current
  448. S_OK,
  449. NULL, // don't update string
  450. NULL
  451. ) );
  452. if ( FAILED( hr ) )
  453. {
  454. goto Cleanup;
  455. }
  456. if ( m_fStop == TRUE )
  457. {
  458. goto Cleanup;
  459. } // if:
  460. //
  461. // Ask the node if it can be clustered.
  462. //
  463. hr = THR( m_pccs->TypeSafeQI( IClusCfgCapabilities, &pccc ) );
  464. if ( FAILED( hr ) )
  465. {
  466. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_QI_pccc, hr );
  467. goto ClusterFeasibilityError;
  468. }
  469. hr = STHR( pccc->CanNodeBeClustered() );
  470. if ( FAILED( hr ) )
  471. {
  472. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_CanNodeBeClustered, hr );
  473. goto ClusterFeasibilityError;
  474. }
  475. if ( hr == S_FALSE )
  476. {
  477. //
  478. // Tell the UI layer that this node doesn't want to be clustered. Note that
  479. // we don't put anything in the UI, only to the log. It is the responsibility
  480. // of the "blocking" component to tell the UI layer the reasons.
  481. //
  482. hr = THR( HRESULT_FROM_WIN32( ERROR_NODE_CANNOT_BE_CLUSTERED ) );
  483. THR( SendStatusReport( m_bstrNodeName,
  484. TASKID_Major_Client_And_Server_Log,
  485. TASKID_Minor_Can_Node_Be_Clustered_Failed,
  486. 0, // min
  487. 1, // max
  488. 1, // current
  489. hr,
  490. NULL,
  491. NULL
  492. ) );
  493. goto ClusterFeasibilityError;
  494. }
  495. //
  496. // Tell the UI layer we're done checking the node's cluster feasibility.
  497. //
  498. hr = THR( SendStatusReport( m_bstrNodeName,
  499. TASKID_Major_Check_Node_Feasibility,
  500. TASKID_Minor_Checking_Node_Cluster_Feasibility,
  501. 0, // min
  502. 2, // max
  503. 2, // current
  504. S_OK,
  505. NULL, // don't update string
  506. NULL
  507. ) );
  508. if ( FAILED( hr ) )
  509. {
  510. goto Cleanup;
  511. }
  512. if ( m_fStop == TRUE )
  513. {
  514. goto Cleanup;
  515. } // if:
  516. //
  517. // Create progress message and tell the UI layer our progress
  518. // for gathering managed resource info.
  519. //
  520. hr = THR( HrSendStatusReport(
  521. m_bstrNodeName
  522. , TASKID_Major_Find_Devices
  523. , TASKID_Minor_Gathering_Managed_Devices
  524. , 0
  525. , 2
  526. , 0
  527. , S_OK
  528. , IDS_TASKID_MINOR_GATHERING_MANAGED_DEVICES
  529. , 0
  530. ) );
  531. if ( FAILED( hr ) )
  532. {
  533. goto FindResourcesError;
  534. }
  535. hr = THR( m_pccs->GetManagedResourcesEnum( &peccmr ) );
  536. if ( FAILED( hr ) )
  537. {
  538. goto FindResourcesError;
  539. }
  540. hr = THR( m_pccs->GetNetworksEnum( &pen ) );
  541. if ( FAILED( hr ) )
  542. {
  543. goto FindResourcesError;
  544. }
  545. hr = THR( HrTotalManagedResourceCount( peccmr, pen, &cTotalResources ) );
  546. if ( FAILED( hr ) )
  547. {
  548. goto FindResourcesError;
  549. }
  550. if ( m_fStop == TRUE )
  551. {
  552. goto Cleanup;
  553. } // if:
  554. //
  555. // Start gathering the managed resources.
  556. //
  557. hr = THR( HrGatherResources( peccmr, cTotalResources ) );
  558. if ( FAILED( hr ) )
  559. {
  560. goto FindResourcesError;
  561. }
  562. //
  563. // Tell the UI layer we're done with gathering the resources.
  564. //
  565. hr = THR( SendStatusReport( m_bstrNodeName,
  566. TASKID_Major_Find_Devices,
  567. TASKID_Minor_Gathering_Managed_Devices,
  568. 0, // min
  569. 2, // max
  570. 1, // current
  571. S_OK,
  572. NULL, // don't update string
  573. NULL
  574. ) );
  575. if ( FAILED( hr ) )
  576. {
  577. goto Cleanup;
  578. }
  579. //
  580. // Now gather the networks from the node.
  581. //
  582. hr = THR( HrGatherNetworks( pen, cTotalResources ) );
  583. if ( FAILED( hr ) )
  584. {
  585. goto FindResourcesError;
  586. }
  587. //
  588. // Tell the UI layer we're done with gathering the networks.
  589. //
  590. hr = THR( SendStatusReport( m_bstrNodeName,
  591. TASKID_Major_Find_Devices,
  592. TASKID_Minor_Gathering_Managed_Devices,
  593. 0, // min
  594. 2, // max
  595. 2, // current
  596. S_OK,
  597. NULL, // don't update string
  598. NULL
  599. ) );
  600. if ( FAILED( hr ) )
  601. {
  602. goto Cleanup;
  603. }
  604. Cleanup:
  605. if ( psp != NULL )
  606. {
  607. psp->Release();
  608. }
  609. if ( punk != NULL )
  610. {
  611. punk->Release();
  612. }
  613. if ( pcp != NULL )
  614. {
  615. pcp->Release();
  616. }
  617. if ( pcpc != NULL )
  618. {
  619. pcpc->Release();
  620. }
  621. if ( m_pom != NULL )
  622. {
  623. HRESULT hr2;
  624. IUnknown * punkTemp = NULL;
  625. hr2 = THR( m_pom->GetObject( DFGUID_StandardInfo,
  626. m_cookieCompletion,
  627. &punkTemp
  628. ) );
  629. if ( SUCCEEDED( hr2 ) )
  630. {
  631. IStandardInfo * psiTemp = NULL;
  632. hr2 = THR( punkTemp->TypeSafeQI( IStandardInfo, &psiTemp ) );
  633. punkTemp->Release();
  634. punkTemp = NULL;
  635. if ( SUCCEEDED( hr2 ) )
  636. {
  637. hr2 = THR( psiTemp->SetStatus( hr ) );
  638. psiTemp->Release();
  639. psiTemp = NULL;
  640. }
  641. else
  642. {
  643. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_GetObject_QI_Failed, hr );
  644. }
  645. }
  646. else
  647. {
  648. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_BeginTask_GetObject_Failed, hr );
  649. }
  650. } // if: ( m_pom != NULL )
  651. if ( pnui != NULL )
  652. {
  653. THR( pnui->ObjectChanged( m_cookieCompletion ) );
  654. pnui->Release();
  655. }
  656. if ( pcm != NULL )
  657. {
  658. pcm->Release();
  659. }
  660. if ( psi != NULL )
  661. {
  662. psi->Release();
  663. }
  664. if ( pccc != NULL )
  665. {
  666. pccc->Release();
  667. }
  668. if ( peccmr != NULL )
  669. {
  670. peccmr->Release();
  671. }
  672. if ( pen != NULL )
  673. {
  674. pen->Release();
  675. }
  676. LogMsg( L"[MT] [CTaskGatherInformation] exiting task. The task was%ws cancelled.", m_fStop == FALSE ? L" not" : L"" );
  677. HRETURN( hr );
  678. ClusterFeasibilityError:
  679. THR( SendStatusReport( m_bstrNodeName,
  680. TASKID_Major_Check_Node_Feasibility,
  681. TASKID_Minor_Checking_Node_Cluster_Feasibility,
  682. 0,
  683. 2,
  684. 2,
  685. hr,
  686. NULL,
  687. NULL
  688. ) );
  689. goto Cleanup;
  690. FindResourcesError:
  691. THR( SendStatusReport( m_bstrNodeName,
  692. TASKID_Major_Find_Devices,
  693. TASKID_Minor_Gathering_Managed_Devices,
  694. 0,
  695. 2,
  696. 2,
  697. hr,
  698. NULL,
  699. NULL
  700. ) );
  701. goto Cleanup;
  702. } //*** CTaskGatherInformation::BeginTask
  703. //////////////////////////////////////////////////////////////////////////////
  704. //
  705. // STDMETHODIMP
  706. // CTaskGatherInformation::StopTask( void )
  707. //
  708. //////////////////////////////////////////////////////////////////////////////
  709. STDMETHODIMP
  710. CTaskGatherInformation::StopTask( void )
  711. {
  712. TraceFunc( "[IDoTask]" );
  713. HRESULT hr = S_OK;
  714. m_fStop = TRUE;
  715. LogMsg( L"[MT] [CTaskGatherInformation] is being stopped." );
  716. HRETURN( hr );
  717. } //*** CTaskGatherInformation::StopTask
  718. //////////////////////////////////////////////////////////////////////////////
  719. //
  720. // STDMETHODIMP
  721. // CTaskGatherInformation::SetCompletionCookie(
  722. // OBJECTCOOKIE cookieIn
  723. // )
  724. //
  725. //////////////////////////////////////////////////////////////////////////////
  726. STDMETHODIMP
  727. CTaskGatherInformation::SetCompletionCookie(
  728. OBJECTCOOKIE cookieIn
  729. )
  730. {
  731. TraceFunc( "[ITaskGatherInformation]" );
  732. HRESULT hr = S_OK;
  733. m_cookieCompletion = cookieIn;
  734. HRETURN( hr );
  735. } //*** CTaskGatherInformation::SetCompletionCookie
  736. //////////////////////////////////////////////////////////////////////////////
  737. //
  738. // STDMETHODIMP
  739. // CTaskGatherInformation::SetNodeCookie(
  740. // OBJECTCOOKIE cookieIn
  741. // )
  742. //
  743. //////////////////////////////////////////////////////////////////////////////
  744. STDMETHODIMP
  745. CTaskGatherInformation::SetNodeCookie(
  746. OBJECTCOOKIE cookieIn
  747. )
  748. {
  749. TraceFunc( "[ITaskGatherInformation]" );
  750. HRESULT hr = S_OK;
  751. m_cookieNode = cookieIn;
  752. HRETURN( hr );
  753. } //*** CTaskGatherInformation::SetNodeCookie
  754. //////////////////////////////////////////////////////////////////////////////
  755. //
  756. // STDMETHODIMP
  757. // CTaskGatherInformation::SetJoining( void )
  758. //
  759. //////////////////////////////////////////////////////////////////////////////
  760. STDMETHODIMP
  761. CTaskGatherInformation::SetJoining( void )
  762. {
  763. TraceFunc( "[ITaskGatherInformation]" );
  764. HRESULT hr = S_OK;
  765. m_fAdding = TRUE;
  766. HRETURN( hr );
  767. } //*** CTaskGatherInformation::SetJoining
  768. //////////////////////////////////////////////////////////////////////////////
  769. //
  770. // STDMETHODIMP
  771. // CTaskGatherInformation::SetMinimalConfiguration(
  772. // BOOL fMinimalConfigurationIn
  773. // )
  774. //
  775. //////////////////////////////////////////////////////////////////////////////
  776. STDMETHODIMP
  777. CTaskGatherInformation::SetMinimalConfiguration(
  778. BOOL fMinimalConfigurationIn
  779. )
  780. {
  781. TraceFunc( "[ITaskGatherInformation]" );
  782. HRESULT hr = S_OK;
  783. m_fMinConfig = fMinimalConfigurationIn;
  784. HRETURN( hr );
  785. } //*** CTaskGatherInformation::SetMinimalConfiguration
  786. //****************************************************************************
  787. //
  788. // IClusCfgCallback
  789. //
  790. //****************************************************************************
  791. //////////////////////////////////////////////////////////////////////////////
  792. //
  793. // STDMETHODIMP
  794. // CTaskGatherInformation::SendStatusReport(
  795. // LPCWSTR pcszNodeNameIn,
  796. // CLSID clsidTaskMajorIn,
  797. // CLSID clsidTaskMinorIn,
  798. // ULONG ulMinIn,
  799. // ULONG ulMaxIn,
  800. // ULONG ulCurrentIn,
  801. // HRESULT hrStatusIn,
  802. // LPCWSTR pcszDescriptionIn,
  803. // LPCWSTR pcszReferenceIn
  804. // )
  805. //
  806. //////////////////////////////////////////////////////////////////////////////
  807. STDMETHODIMP
  808. CTaskGatherInformation::SendStatusReport(
  809. LPCWSTR pcszNodeNameIn
  810. , CLSID clsidTaskMajorIn
  811. , CLSID clsidTaskMinorIn
  812. , ULONG ulMinIn
  813. , ULONG ulMaxIn
  814. , ULONG ulCurrentIn
  815. , HRESULT hrStatusIn
  816. , LPCWSTR pcszDescriptionIn
  817. , LPCWSTR pcszReferenceIn
  818. )
  819. {
  820. TraceFunc( "" );
  821. Assert( pcszNodeNameIn != NULL );
  822. HRESULT hr = S_OK;
  823. IServiceProvider * psp = NULL;
  824. IConnectionPointContainer * pcpc = NULL;
  825. IConnectionPoint * pcp = NULL;
  826. FILETIME ft;
  827. if ( m_pcccb == NULL )
  828. {
  829. //
  830. // Collect the manager we need to complete this task.
  831. //
  832. hr = THR( CoCreateInstance( CLSID_ServiceManager,
  833. NULL,
  834. CLSCTX_INPROC_SERVER,
  835. TypeSafeParams( IServiceProvider, &psp )
  836. ) );
  837. if ( FAILED( hr ) )
  838. {
  839. goto Cleanup;
  840. }
  841. hr = THR( psp->TypeSafeQS( CLSID_NotificationManager,
  842. IConnectionPointContainer,
  843. &pcpc
  844. ) );
  845. if ( FAILED( hr ) )
  846. {
  847. goto Cleanup;
  848. }
  849. hr = THR( pcpc->FindConnectionPoint( IID_IClusCfgCallback, &pcp ) );
  850. if ( FAILED( hr ) )
  851. {
  852. goto Cleanup;
  853. }
  854. pcp = TraceInterface( L"CTaskGatherInformation!IConnectionPoint", IConnectionPoint, pcp, 1 );
  855. hr = THR( pcp->TypeSafeQI( IClusCfgCallback, &m_pcccb ) );
  856. if ( FAILED( hr ) )
  857. {
  858. goto Cleanup;
  859. }
  860. m_pcccb = TraceInterface( L"CTaskGatherInformation!IClusCfgCallback", IClusCfgCallback, m_pcccb, 1 );
  861. psp->Release();
  862. psp = NULL;
  863. } // if: no IClusCfgCallback interface QI'd for yet
  864. GetSystemTimeAsFileTime( &ft );
  865. //
  866. // Send the message!
  867. //
  868. hr = THR( m_pcccb->SendStatusReport( pcszNodeNameIn,
  869. clsidTaskMajorIn,
  870. clsidTaskMinorIn,
  871. ulMinIn,
  872. ulMaxIn,
  873. ulCurrentIn,
  874. hrStatusIn,
  875. pcszDescriptionIn,
  876. &ft,
  877. pcszReferenceIn
  878. ) );
  879. Cleanup:
  880. if ( psp != NULL )
  881. {
  882. psp->Release();
  883. }
  884. if ( pcpc != NULL )
  885. {
  886. pcpc->Release();
  887. }
  888. if ( pcp != NULL )
  889. {
  890. pcp->Release();
  891. }
  892. HRETURN( hr );
  893. } //*** CTaskGatherInformation::SendStatusReport
  894. //****************************************************************************
  895. //
  896. // Private
  897. //
  898. //****************************************************************************
  899. //////////////////////////////////////////////////////////////////////////////
  900. //++
  901. //
  902. // CTaskGatherInformation::HrGatherResources
  903. //
  904. // Description:
  905. //
  906. // Arguments:
  907. // pResourceEnumIn -
  908. // cTotalResourcesIn -
  909. //
  910. // Return Values:
  911. //
  912. //--
  913. //////////////////////////////////////////////////////////////////////////////
  914. HRESULT
  915. CTaskGatherInformation::HrGatherResources(
  916. IEnumClusCfgManagedResources * pResourceEnumIn
  917. , DWORD cTotalResourcesIn
  918. )
  919. {
  920. TraceFunc( "" );
  921. HRESULT hr = S_OK;
  922. ULONG celt;
  923. OBJECTCOOKIE cookieDummy;
  924. ULONG celtFetched = 0;
  925. BSTR bstrName = NULL;
  926. BSTR bstrNotification = NULL;
  927. BOOL fFoundQuorumResource = FALSE;
  928. BOOL fFoundOptimalSizeQuorum = FALSE;
  929. BOOL fFoundQuorumCapablePartition = FALSE;
  930. BOOL fIsQuorumCapable = FALSE;
  931. BSTR bstrQuorumResourceName = NULL;
  932. IEnumClusCfgPartitions * peccp = NULL;
  933. IClusCfgManagedResourceInfo * pccmriClientSide = NULL;
  934. IClusCfgManagedResourceInfo * pccmriServerSide[ 10 ] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
  935. HRESULT hrTemp;
  936. CLSID clsidMinorId;
  937. if ( pResourceEnumIn == NULL )
  938. {
  939. hr = THR( E_POINTER );
  940. goto Error;
  941. }
  942. //
  943. // Initialize some stuff.
  944. //
  945. m_ulQuorumDiskSize = ULONG_MAX;
  946. Assert( m_pccmriQuorum == NULL );
  947. THR( SendStatusReport(
  948. m_bstrNodeName
  949. , TASKID_Major_Update_Progress
  950. , TASKID_Major_Gather_Resources
  951. , 0
  952. , cTotalResourcesIn + 2
  953. , 0
  954. , S_OK
  955. , NULL
  956. , NULL
  957. ) );
  958. //
  959. // Enumerate the next 10 resources.
  960. //
  961. while ( ( hr == S_OK ) && ( m_fStop == FALSE ) )
  962. {
  963. //
  964. // KB: GPease 27-JUL-2000
  965. // We decided to enumerate one at a time because WMI is
  966. // taking so long on the server side that the UI needs
  967. // some kind of feedback. Having the server send a
  968. // message back seemed to be expensive especially
  969. // since grabbing 10 at a time was supposed to save
  970. // us bandwidth on the wire.
  971. //
  972. // KB: DavidP 24-JUL-2001
  973. // According to GalenB, this is not longer an issue, since once
  974. // the server has collected information for one resource, it has
  975. // collected information for all of them.
  976. //
  977. hr = STHR( pResourceEnumIn->Next( 10, pccmriServerSide, &celtFetched ) );
  978. //hr = STHR( pResourceEnumIn->Next( 1, pccmriServerSide, &celtFetched ) );
  979. if ( ( hr == S_FALSE ) && ( celtFetched == 0 ) )
  980. {
  981. break; // exit loop
  982. }
  983. if ( FAILED( hr ) )
  984. {
  985. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_Next, hr );
  986. goto Error;
  987. }
  988. //
  989. // Loop thru the resource gather information out of each of them
  990. // and then release them.
  991. //
  992. for ( celt = 0 ; ( ( celt < celtFetched ) && ( m_fStop == FALSE ) ); celt ++ )
  993. {
  994. UINT uIdMessage = IDS_TASKID_MINOR_FOUND_RESOURCE;
  995. IGatherData * pgd;
  996. IUnknown * punk;
  997. Assert( pccmriServerSide[ celt ] != NULL );
  998. // get the name of the resource
  999. hr = THR( pccmriServerSide[ celt ]->GetUID( &bstrName ) );
  1000. if ( FAILED( hr ) )
  1001. {
  1002. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_GetUID, hr );
  1003. goto Error;
  1004. }
  1005. TraceMemoryAddBSTR( bstrName );
  1006. // make sure the object manager generates a cookie for it.
  1007. hr = STHR( m_pom->FindObject( CLSID_ManagedResourceType,
  1008. m_cookieNode,
  1009. bstrName,
  1010. DFGUID_ManagedResource,
  1011. &cookieDummy,
  1012. &punk
  1013. ) );
  1014. if ( FAILED( hr ) )
  1015. {
  1016. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_FindObject, hr );
  1017. goto Error;
  1018. }
  1019. TraceSysFreeString( bstrName );
  1020. bstrName = NULL;
  1021. hr = THR( punk->TypeSafeQI( IClusCfgManagedResourceInfo, &pccmriClientSide ) );
  1022. punk->Release(); // release promptly
  1023. if ( FAILED( hr ) )
  1024. {
  1025. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_FindObject_QI_pccmriClientSide, hr );
  1026. goto Error;
  1027. }
  1028. //
  1029. // The Object Manager created a new object. Initialize it.
  1030. //
  1031. // Find the IGatherData interface.
  1032. hr = THR( pccmriClientSide->TypeSafeQI( IGatherData, &pgd ) );
  1033. if ( FAILED( hr ) )
  1034. {
  1035. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_FindObject_QI_pgd, hr );
  1036. goto Error;
  1037. }
  1038. // Have the new object gather all information it needs.
  1039. hr = THR( pgd->Gather( m_cookieNode, pccmriServerSide[ celt ] ) );
  1040. pgd->Release(); // release promptly
  1041. if ( FAILED( hr ) )
  1042. {
  1043. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_Gather, hr );
  1044. goto Error;
  1045. }
  1046. // Figure out if the resource is capable of being a quorum resource.
  1047. hr = STHR( pccmriClientSide->IsQuorumCapable() );
  1048. if ( FAILED( hr ) )
  1049. {
  1050. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_IsQuorumCapable, hr );
  1051. goto Error;
  1052. }
  1053. if ( hr == S_OK )
  1054. {
  1055. uIdMessage = IDS_TASKID_MINOR_FOUND_QUORUM_CAPABLE_RESOURCE;
  1056. //
  1057. // If we aren't adding nodes, then figure out if this resource
  1058. // is a better quorum resource than one previously encountered.
  1059. //
  1060. //
  1061. // If minimal analysis and configuration was selected then we don't want to
  1062. // choose a quorum resource.
  1063. //
  1064. if ( ( m_fAdding == FALSE ) && ( m_fMinConfig == FALSE ) )
  1065. {
  1066. ULONG ulMegaBytes;
  1067. // Don't wrap - this can fail with NO_INTERFACE.
  1068. hr = pccmriServerSide[ celt ]->TypeSafeQI( IEnumClusCfgPartitions, &peccp );
  1069. if ( SUCCEEDED( hr ) )
  1070. {
  1071. //
  1072. // We don't know if this resource is quorum capable, so this flag is set to FALSE right before the while loop
  1073. //
  1074. fIsQuorumCapable = FALSE;
  1075. while ( SUCCEEDED( hr ) )
  1076. {
  1077. ULONG celtDummy;
  1078. IClusCfgPartitionInfo * pccpi;
  1079. hr = STHR( peccp->Next( 1, &pccpi, &celtDummy ) );
  1080. if ( FAILED( hr ) )
  1081. {
  1082. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_EnumPartitions_Next, hr );
  1083. goto Error;
  1084. }
  1085. if ( hr == S_FALSE )
  1086. {
  1087. break; // exit condition
  1088. }
  1089. hr = THR( pccpi->GetSize( &ulMegaBytes ) );
  1090. pccpi->Release(); // release promptly
  1091. if ( FAILED( hr ) )
  1092. {
  1093. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_EnumPartitions_GetSize, hr );
  1094. goto Error;
  1095. }
  1096. //
  1097. // This section below represents our quorum resource selection logic:
  1098. // Does this partition meet the minimum requirements for a quorum resource?
  1099. // And is it smaller than the last selected quorum resource?
  1100. //
  1101. if ( ( ulMegaBytes >= OPTIMUM_STORAGE_SIZE ) && ( ( ulMegaBytes < m_ulQuorumDiskSize ) || ( m_ulQuorumDiskSize < OPTIMUM_STORAGE_SIZE ) ) )
  1102. {
  1103. fFoundQuorumCapablePartition = TRUE;
  1104. fFoundOptimalSizeQuorum = TRUE;
  1105. } // if: partition meets optimum requirements
  1106. else if ( ( fFoundOptimalSizeQuorum == FALSE ) && ( ulMegaBytes >= MINIMUM_STORAGE_SIZE ) )
  1107. {
  1108. if ( ( fFoundQuorumResource == FALSE ) || ( ulMegaBytes > m_ulQuorumDiskSize ) )
  1109. {
  1110. fFoundQuorumCapablePartition = TRUE;
  1111. } // if: ( ( fFoundQuorumResource == FALSE ) || ( ulMegaBytes > m_ulQuorumDiskSize ) )
  1112. } // else if: there is a partition that satisfies minimum requirements
  1113. //
  1114. // Per our quourum selection logic, if fFoundQuorumCapablePartition == TRUE, we select this resource to be the quorum.
  1115. //
  1116. if ( fFoundQuorumCapablePartition == TRUE )
  1117. {
  1118. fFoundQuorumCapablePartition = FALSE;
  1119. fFoundQuorumResource = TRUE;
  1120. if ( m_pccmriQuorum != pccmriClientSide )
  1121. {
  1122. // Set the new resource as quorum.
  1123. hr = THR( pccmriClientSide->SetQuorumResource( TRUE ) );
  1124. if ( FAILED( hr ) )
  1125. {
  1126. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_EnumPartitions_SetNEWQuorumedDevice, hr );
  1127. goto Error;
  1128. }
  1129. if ( m_pccmriQuorum != NULL )
  1130. {
  1131. // Delete the old quorum resource name.
  1132. TraceSysFreeString( bstrQuorumResourceName );
  1133. bstrQuorumResourceName = NULL;
  1134. // Unset the old resource.
  1135. hr = THR( m_pccmriQuorum->SetQuorumResource( FALSE ) );
  1136. if ( FAILED( hr ) )
  1137. {
  1138. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_EnumPartitions_SetOLDQuorumedDevice, hr );
  1139. goto Error;
  1140. }
  1141. // Release the interface.
  1142. m_pccmriQuorum->Release();
  1143. }
  1144. hr = THR( pccmriClientSide->GetUID( &bstrQuorumResourceName ) );
  1145. if ( FAILED( hr ) )
  1146. {
  1147. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_EnumPartitions_GetUID, hr );
  1148. goto Error;
  1149. }
  1150. TraceMemoryAddBSTR( bstrQuorumResourceName );
  1151. m_pccmriQuorum = pccmriClientSide;
  1152. m_pccmriQuorum->AddRef();
  1153. }
  1154. m_ulQuorumDiskSize = ulMegaBytes;
  1155. } // if: ( fFoundQuorumCapablePartition == TRUE )
  1156. //
  1157. // If any partition on this resource is larger than the minimum storage size, set fIsQuorumCapable to TRUE
  1158. //
  1159. if ( ulMegaBytes >= MINIMUM_STORAGE_SIZE )
  1160. {
  1161. fIsQuorumCapable = TRUE;
  1162. }
  1163. } // while: success
  1164. peccp->Release();
  1165. peccp = NULL;
  1166. //
  1167. // If there was no partition that met the minimum storage size, set this resource as NOT quorum capable.
  1168. //
  1169. if ( fIsQuorumCapable == FALSE )
  1170. {
  1171. hr = THR( pccmriClientSide->SetQuorumCapable( fIsQuorumCapable ) );
  1172. if ( FAILED( hr ) )
  1173. {
  1174. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_SetQuorumCapable, hr );
  1175. goto Error;
  1176. }
  1177. }
  1178. } // if: partition capable
  1179. else
  1180. {
  1181. if ( hr != E_NOINTERFACE )
  1182. {
  1183. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_QI_peccp, hr );
  1184. THR( hr );
  1185. goto Error;
  1186. }
  1187. } // else: failed
  1188. } // if: not joining
  1189. else
  1190. {
  1191. //
  1192. // If we are adding, then a quorum resource had to be
  1193. // found already.
  1194. //
  1195. //
  1196. // BUGBUG: 08-MAY-2001 GalenB
  1197. //
  1198. // We are not setting bstrQuorumResourceName to something
  1199. // if we are adding. This causes the message "Setting
  1200. // quorum resource to '(NULL)' to appear in the logs and
  1201. // the UI. Where is the quorum when we are adding a node
  1202. // to the cluster?
  1203. //
  1204. // A more complete fix is to find the current quorum
  1205. // resource and get its name.
  1206. //
  1207. fFoundQuorumResource = TRUE;
  1208. } // else: joining
  1209. } // if: quorum capable
  1210. // send the UI layer a report
  1211. m_cResources ++;
  1212. // grab the name to display in the UI
  1213. hr = THR( pccmriClientSide->GetName( &bstrName ) );
  1214. if ( FAILED( hr ) )
  1215. {
  1216. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_GetName, hr );
  1217. goto Error;
  1218. }
  1219. TraceMemoryAddBSTR( bstrName );
  1220. hr = THR( HrFormatMessageIntoBSTR( g_hInstance, uIdMessage, &bstrNotification, bstrName ) );
  1221. if ( FAILED( hr ) )
  1222. {
  1223. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_EnumResources_FormatMessage, hr );
  1224. goto Error;
  1225. }
  1226. hrTemp = THR( CoCreateGuid( &clsidMinorId ) );
  1227. if ( FAILED( hrTemp ) )
  1228. {
  1229. LogMsg( L"[MT] Could not create a guid for a managed resource minor task ID" );
  1230. clsidMinorId = IID_NULL;
  1231. } // if:
  1232. //
  1233. // Show this resource under "Collecting Managed Resources..."
  1234. //
  1235. hr = THR( ::HrSendStatusReport(
  1236. m_pcccb
  1237. , m_bstrNodeName
  1238. , TASKID_Minor_Gathering_Managed_Devices
  1239. , clsidMinorId
  1240. , 1
  1241. , 1
  1242. , 1
  1243. , S_OK
  1244. , bstrNotification
  1245. ) );
  1246. if ( FAILED( hr ) )
  1247. {
  1248. goto Cleanup;
  1249. } // if:
  1250. //
  1251. // Simply update the progress bar "tick".
  1252. //
  1253. hr = THR( SendStatusReport(
  1254. m_bstrNodeName
  1255. , TASKID_Major_Update_Progress
  1256. , TASKID_Major_Gather_Resources
  1257. , 0
  1258. , cTotalResourcesIn + 2
  1259. , m_cResources + 1
  1260. , S_OK
  1261. , NULL
  1262. , NULL
  1263. ) );
  1264. if ( FAILED( hr ) )
  1265. {
  1266. goto Cleanup;
  1267. }
  1268. // Cleanup for the next resource.
  1269. TraceSysFreeString( bstrName );
  1270. bstrName = NULL;
  1271. pccmriClientSide->Release();
  1272. pccmriClientSide = NULL;
  1273. // release the interface
  1274. pccmriServerSide[ celt ]->Release();
  1275. pccmriServerSide[ celt ] = NULL;
  1276. } // for: celt
  1277. } // while: hr
  1278. if ( m_fStop == TRUE )
  1279. {
  1280. goto Cleanup;
  1281. } // if:
  1282. //
  1283. // Update UI layer about the quorum resource.
  1284. //
  1285. //
  1286. // BUGUG: 08-MAY-2001 GalenB
  1287. //
  1288. // Testing that bstrQuorumResourceName has something in it before showing
  1289. // this in the UI. When adding nodes this variable is not being set and
  1290. // was causing a status report with a NULL name to be shown in the UI.
  1291. //
  1292. if ( fFoundQuorumResource == TRUE )
  1293. {
  1294. if ( bstrQuorumResourceName != NULL )
  1295. {
  1296. Assert( m_fAdding == FALSE );
  1297. if ( fFoundOptimalSizeQuorum == TRUE )
  1298. {
  1299. //
  1300. // Display a message in UI telling we found a quorum capable resource
  1301. //
  1302. THR( HrSendStatusReport(
  1303. m_bstrNodeName
  1304. , TASKID_Major_Find_Devices
  1305. , TASKID_Minor_Found_Quorum_Capable_Resource
  1306. , 1
  1307. , 1
  1308. , 1
  1309. , S_OK
  1310. , IDS_TASKID_MINOR_FOUND_A_QUORUM_CAPABLE_RESOURCE
  1311. , 0
  1312. ) );
  1313. } // if: optimal size quorum resource found
  1314. else
  1315. {
  1316. TraceSysFreeString( bstrNotification );
  1317. bstrNotification = NULL;
  1318. THR( HrFormatStringIntoBSTR(
  1319. g_hInstance
  1320. , IDS_TASKID_MINOR_FOUND_MINIMUM_SIZE_QUORUM_CAPABLE_RESOURCE
  1321. , &bstrNotification
  1322. , bstrQuorumResourceName
  1323. ) );
  1324. //
  1325. // Display a warning in UI since we found a minimum size quorum resource
  1326. //
  1327. hr = THR( SendStatusReport(
  1328. m_bstrNodeName
  1329. , TASKID_Major_Find_Devices
  1330. , TASKID_Minor_Found_Minimum_Size_Quorum_Capable_Resource
  1331. , 1
  1332. , 1
  1333. , 1
  1334. , S_FALSE
  1335. , bstrNotification
  1336. , 0
  1337. ) );
  1338. } // minimum size quorum resource found
  1339. TraceSysFreeString( bstrNotification );
  1340. bstrNotification = NULL;
  1341. THR( HrFormatStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_MARKING_QUORUM_CAPABLE_RESOURCE, &bstrNotification, bstrQuorumResourceName ) );
  1342. hr = THR( SendStatusReport( m_bstrNodeName,
  1343. TASKID_Major_Find_Devices,
  1344. TASKID_Minor_Marking_Quorum_Capable_Resource,
  1345. 1,
  1346. 1,
  1347. 1,
  1348. S_OK,
  1349. bstrNotification,
  1350. NULL
  1351. ) );
  1352. TraceSysFreeString( bstrNotification );
  1353. bstrNotification = NULL;
  1354. } // if: we have a quorum resource to show
  1355. } // if: found a quorum resource
  1356. else
  1357. {
  1358. if ( m_fAdding == TRUE )
  1359. {
  1360. //
  1361. // If adding, stop the user.
  1362. //
  1363. hr = THR( HrFormatMessageIntoBSTR( g_hInstance,
  1364. IDS_TASKID_MINOR_NO_QUORUM_CAPABLE_RESOURCE_FOUND,
  1365. &bstrNotification,
  1366. m_bstrNodeName
  1367. ) );
  1368. hr = THR( SendStatusReport( m_bstrNodeName,
  1369. TASKID_Major_Find_Devices,
  1370. TASKID_Minor_No_Quorum_Capable_Device_Found,
  1371. 1,
  1372. 1,
  1373. 1,
  1374. HRESULT_FROM_WIN32( TW32( ERROR_QUORUM_DISK_NOT_FOUND ) ),
  1375. bstrNotification,
  1376. NULL
  1377. ) );
  1378. TraceSysFreeString( bstrNotification );
  1379. bstrNotification = NULL;
  1380. // error checked below
  1381. } // if: adding nodes
  1382. else
  1383. {
  1384. //
  1385. // If creating, just warn the user.
  1386. //
  1387. hr = THR( HrFormatMessageIntoBSTR( g_hInstance,
  1388. IDS_TASKID_MINOR_FORCED_LOCAL_QUORUM,
  1389. &bstrNotification
  1390. ) );
  1391. hr = THR( SendStatusReport( m_bstrNodeName,
  1392. TASKID_Major_Find_Devices,
  1393. TASKID_Minor_No_Quorum_Capable_Device_Found,
  1394. 1,
  1395. 1,
  1396. 1,
  1397. MAKE_HRESULT( SEVERITY_SUCCESS, FACILITY_WIN32, ERROR_QUORUM_DISK_NOT_FOUND ),
  1398. bstrNotification,
  1399. NULL
  1400. ) );
  1401. TraceSysFreeString( bstrNotification );
  1402. bstrNotification = NULL;
  1403. // error checked below
  1404. } // else: creating a cluster
  1405. } // else: no quorum detected.
  1406. //
  1407. // Check error and do the appropriate thing.
  1408. //
  1409. if ( FAILED( hr ) )
  1410. {
  1411. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherResources_Failed, hr );
  1412. goto Cleanup;
  1413. }
  1414. hr = S_OK;
  1415. Cleanup:
  1416. THR( SendStatusReport(
  1417. m_bstrNodeName
  1418. , TASKID_Major_Update_Progress
  1419. , TASKID_Major_Gather_Resources
  1420. , 0
  1421. , cTotalResourcesIn + 2
  1422. , cTotalResourcesIn + 2
  1423. , S_OK
  1424. , NULL
  1425. , NULL
  1426. ) );
  1427. TraceSysFreeString( bstrName );
  1428. TraceSysFreeString( bstrNotification );
  1429. TraceSysFreeString( bstrQuorumResourceName );
  1430. if ( peccp != NULL )
  1431. {
  1432. peccp->Release();
  1433. }
  1434. if ( pccmriClientSide != NULL )
  1435. {
  1436. pccmriClientSide->Release();
  1437. }
  1438. for( celt = 0; celt < 10; celt ++ )
  1439. {
  1440. if ( pccmriServerSide[ celt ] != NULL )
  1441. {
  1442. pccmriServerSide[ celt ]->Release();
  1443. }
  1444. } // for: celt
  1445. HRETURN( hr );
  1446. Error:
  1447. //
  1448. // Tell the UI layer we're done will gathering and what the resulting
  1449. // status was.
  1450. //
  1451. THR( HrSendStatusReport(
  1452. m_bstrNodeName
  1453. , TASKID_Major_Find_Devices
  1454. , TASKID_Minor_Gathering_Managed_Devices
  1455. , 0
  1456. , 2
  1457. , 2
  1458. , hr
  1459. , IDS_ERR_TGI_FAILED_TRY_TO_REANALYZE
  1460. , 0
  1461. ) );
  1462. goto Cleanup;
  1463. } //*** CTaskGatherInformation::HrGatherResources
  1464. //////////////////////////////////////////////////////////////////////////////
  1465. //++
  1466. //
  1467. // CTaskGatherInformation::HrGatherNetworks
  1468. //
  1469. // Description:
  1470. //
  1471. // Arguments:
  1472. // pNetworkEnumIn -
  1473. // cTotalNetworksIn -
  1474. //
  1475. // Return Values:
  1476. //
  1477. //--
  1478. //////////////////////////////////////////////////////////////////////////////
  1479. HRESULT
  1480. CTaskGatherInformation::HrGatherNetworks(
  1481. IEnumClusCfgNetworks * pNetworkEnumIn
  1482. , DWORD cTotalNetworksIn
  1483. )
  1484. {
  1485. TraceFunc( "" );
  1486. HRESULT hr = S_OK;
  1487. ULONG celt;
  1488. OBJECTCOOKIE cookieDummy;
  1489. ULONG celtFetched = 0;
  1490. ULONG celtFound = 0;
  1491. BSTR bstrUID = NULL;
  1492. BSTR bstrName = NULL;
  1493. BSTR bstrNotification = NULL;
  1494. IClusCfgNetworkInfo * pccniLocal = NULL;
  1495. IClusCfgNetworkInfo * pccni[ 10 ] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
  1496. HRESULT hrTemp;
  1497. CLSID clsidMinorId;
  1498. hr = THR( SendStatusReport(
  1499. m_bstrNodeName
  1500. , TASKID_Major_Update_Progress
  1501. , TASKID_Major_Gather_Networks
  1502. , 0
  1503. , cTotalNetworksIn + 2
  1504. , 0
  1505. , S_OK
  1506. , NULL
  1507. , NULL
  1508. ) );
  1509. //
  1510. // Enumerate the next 10 networks.
  1511. //
  1512. while ( ( hr == S_OK ) && ( m_fStop == FALSE ) )
  1513. {
  1514. //
  1515. // KB: GPease 27-JUL-2000
  1516. // We decided to enumerate one at a time because WMI is
  1517. // taking so long on the server side that the UI needs
  1518. // some kind of feedback. Having the server send a
  1519. // message back seemed to be expensive especially
  1520. // since grabbing 10 at a time was supposed to save
  1521. // us bandwidth on the wire.
  1522. //
  1523. // KB: DavidP 24-JUL-2001
  1524. // According to GalenB, this is no longer an issue, since once
  1525. // the server has collected information for one network, it has
  1526. // collected information for all of them.
  1527. //
  1528. hr = STHR( pNetworkEnumIn->Next( 10, pccni, &celtFetched ) );
  1529. //hr = STHR( pNetworkEnumIn->Next( 1, pccni, &celtFetched ) );
  1530. if ( hr == S_FALSE && celtFetched == 0 )
  1531. {
  1532. break; // exit loop
  1533. }
  1534. if ( FAILED( hr ) )
  1535. {
  1536. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherNetworks_EnumNetworks_Next, hr );
  1537. goto Error;
  1538. }
  1539. //
  1540. // Loop thru the networks gather information out of each of them
  1541. // and then release them.
  1542. //
  1543. for ( celt = 0 ; ( ( celt < celtFetched ) && ( m_fStop == FALSE ) ); celt ++ )
  1544. {
  1545. IGatherData * pgd;
  1546. IUnknown * punk;
  1547. Assert( pccni[ celt ] != NULL );
  1548. // Get the UID of the network.
  1549. hr = THR( pccni[ celt ]->GetUID( &bstrUID ) );
  1550. if ( FAILED( hr ) )
  1551. {
  1552. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherNetworks_EnumNetworks_GetUID, hr );
  1553. goto Error;
  1554. }
  1555. TraceMemoryAddBSTR( bstrUID );
  1556. // Get the Name of the network.
  1557. hr = THR( pccni[ celt ]->GetName( &bstrName ) );
  1558. if ( FAILED( hr ) )
  1559. {
  1560. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherNetworks_EnumNetworks_GetName, hr );
  1561. goto Error;
  1562. }
  1563. TraceMemoryAddBSTR( bstrName );
  1564. // Make sure the object manager generates a cookie for it.
  1565. hr = STHR( m_pom->FindObject( CLSID_NetworkType,
  1566. m_cookieNode,
  1567. bstrUID,
  1568. DFGUID_NetworkResource,
  1569. &cookieDummy,
  1570. &punk
  1571. ) );
  1572. if ( FAILED( hr ) )
  1573. {
  1574. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherNetworks_EnumNetworks_FindObject, hr );
  1575. goto Error;
  1576. }
  1577. //
  1578. // The Object Manager created a new object. Initialize it.
  1579. //
  1580. // Find the IGatherData interface
  1581. hr = THR( punk->TypeSafeQI( IClusCfgNetworkInfo, &pccniLocal ) );
  1582. punk->Release(); // release promptly
  1583. if ( FAILED( hr ) )
  1584. {
  1585. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherNetworks_EnumNetworks_FindObject_QI_pccniLocal, hr );
  1586. goto Error;
  1587. }
  1588. // Find the IGatherData interface
  1589. hr = THR( pccniLocal->TypeSafeQI( IGatherData, &pgd ) );
  1590. if ( FAILED( hr ) )
  1591. {
  1592. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherNetworks_EnumNetworks_FindObject_QI_pgd, hr );
  1593. goto Error;
  1594. }
  1595. // Have the new object gather all information it needs
  1596. hr = THR( pgd->Gather( m_cookieNode, pccni[ celt ] ) );
  1597. pgd->Release(); // release promptly
  1598. if ( hr == E_UNEXPECTED )
  1599. {
  1600. //
  1601. // Add the parent item.
  1602. //
  1603. hr = THR( HrSendStatusReport(
  1604. m_bstrNodeName
  1605. , TASKID_Major_Find_Devices
  1606. , TASKID_Minor_Not_Managed_Networks
  1607. , 1
  1608. , 1
  1609. , 1
  1610. , S_OK
  1611. , IDS_INFO_NOT_MANAGED_NETWORKS
  1612. , IDS_INFO_NOT_MANAGED_NETWORKS_REF
  1613. ) );
  1614. if ( FAILED( hr ) )
  1615. {
  1616. goto Cleanup;
  1617. }
  1618. //
  1619. // Construct the description string and get a GUID for the
  1620. // minor ID.
  1621. //
  1622. hrTemp = THR( HrFormatStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_DUPLICATE_NETWORKS_FOUND, &bstrNotification, bstrName ) );
  1623. if ( FAILED( hrTemp ) )
  1624. {
  1625. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherNetworks_EnumNetworks_FormatMessage, hrTemp );
  1626. if ( bstrNotification != NULL )
  1627. {
  1628. TraceSysFreeString( bstrNotification );
  1629. bstrNotification = NULL;
  1630. }
  1631. } // if: failed to format message
  1632. hrTemp = THR( CoCreateGuid( &clsidMinorId ) );
  1633. if ( FAILED( hrTemp ) )
  1634. {
  1635. LogMsg( L"[MT] Could not create a guid for a managed network minor task ID." );
  1636. clsidMinorId = IID_NULL;
  1637. } // if:
  1638. //
  1639. // Send the specific report.
  1640. //
  1641. hr = THR( HrSendStatusReport(
  1642. m_bstrNodeName
  1643. , TASKID_Minor_Not_Managed_Networks
  1644. , clsidMinorId
  1645. , 1
  1646. , 1
  1647. , 1
  1648. , S_OK
  1649. , bstrNotification != NULL ? bstrNotification : L"An adapter with a duplicate IP address and subnet was found."
  1650. , IDS_TASKID_MINOR_DUPLICATE_NETWORKS_FOUND_REF
  1651. ) );
  1652. if ( FAILED( hr ) )
  1653. {
  1654. goto Cleanup;
  1655. }
  1656. TraceSysFreeString( bstrNotification );
  1657. bstrNotification = NULL;
  1658. //
  1659. // Simply update the progress bar "tick".
  1660. //
  1661. hr = THR( SendStatusReport(
  1662. m_bstrNodeName
  1663. , TASKID_Major_Update_Progress
  1664. , TASKID_Major_Gather_Networks
  1665. , 0
  1666. , cTotalNetworksIn + 2
  1667. , m_cResources + 2 // the resource number it would have been
  1668. , S_OK
  1669. , L"An adapter with a duplicate IP address and subnet was found."
  1670. , NULL
  1671. ) );
  1672. if ( FAILED( hr ) )
  1673. {
  1674. goto Cleanup;
  1675. }
  1676. // Ignore the error since the cluster will just ignore
  1677. // duplicate networks.
  1678. hr = S_OK;
  1679. goto CleanupLoop;
  1680. } // if: GatherData returned E_UNEXPECTED
  1681. else if ( FAILED( hr ) )
  1682. {
  1683. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherNetworks_EnumNetworks_Gather, hr );
  1684. goto Error;
  1685. }
  1686. m_cResources ++;
  1687. //
  1688. // Send the UI layer a report
  1689. //
  1690. hrTemp = THR( HrFormatMessageIntoBSTR( g_hInstance, IDS_TASKID_MINOR_FOUND_NETWORK, &bstrNotification, bstrName ) );
  1691. if ( FAILED( hrTemp ) )
  1692. {
  1693. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherNetworks_EnumNetworks_FormatMessage, hrTemp );
  1694. if ( bstrNotification != NULL )
  1695. {
  1696. TraceSysFreeString( bstrNotification );
  1697. bstrNotification = NULL;
  1698. }
  1699. } // if: failed to format message
  1700. hrTemp = THR( CoCreateGuid( &clsidMinorId ) );
  1701. if ( FAILED( hrTemp ) )
  1702. {
  1703. LogMsg( L"[MT] Could not create a guid for a managed network minor task ID." );
  1704. clsidMinorId = IID_NULL;
  1705. } // if: failed to create a new guid
  1706. //
  1707. // Show this network under "Collecting Managed Resources..."
  1708. //
  1709. hr = THR( ::HrSendStatusReport(
  1710. m_pcccb
  1711. , m_bstrNodeName
  1712. , TASKID_Minor_Gathering_Managed_Devices
  1713. , clsidMinorId
  1714. , 1
  1715. , 1
  1716. , 1
  1717. , S_OK
  1718. , bstrNotification != NULL ? bstrNotification : L"The description for this entry could not be located."
  1719. ) );
  1720. if ( FAILED( hr ) )
  1721. {
  1722. goto Cleanup;
  1723. } // if:
  1724. TraceSysFreeString( bstrNotification );
  1725. bstrNotification = NULL;
  1726. //
  1727. // Simply update the progress bar "tick".
  1728. //
  1729. hr = THR( SendStatusReport(
  1730. m_bstrNodeName
  1731. , TASKID_Major_Update_Progress
  1732. , TASKID_Major_Gather_Networks
  1733. , 0
  1734. , cTotalNetworksIn + 2
  1735. , m_cResources + 1
  1736. , S_OK
  1737. , NULL
  1738. , NULL
  1739. ) );
  1740. if ( FAILED( hr ) )
  1741. {
  1742. goto Cleanup;
  1743. }
  1744. // Found a Network Interface, increment the counter
  1745. celtFound++;
  1746. CleanupLoop:
  1747. // Clean up before next pass
  1748. TraceSysFreeString( bstrUID );
  1749. TraceSysFreeString( bstrName );
  1750. bstrUID = NULL;
  1751. bstrName = NULL;
  1752. // Release the interface
  1753. pccni[ celt ]->Release();
  1754. pccni[ celt ] = NULL;
  1755. pccniLocal->Release();
  1756. pccniLocal = NULL;
  1757. } // for: each network
  1758. } // while: hr
  1759. if ( m_fStop == TRUE )
  1760. {
  1761. goto Cleanup;
  1762. } // if:
  1763. // Check how many interfaces have been found. Should be at
  1764. // least 2 to avoid single point of failure. If not, warn.
  1765. if ( celtFound < 2 )
  1766. {
  1767. hr = THR( HrFormatMessageIntoBSTR( g_hInstance, IDS_TASKID_MINOR_ONLY_ONE_NETWORK, &bstrNotification ) );
  1768. if ( FAILED( hr ) )
  1769. {
  1770. SSR_TGI_FAILED( TASKID_Major_Client_And_Server_Log, TASKID_Minor_GatherNetworks_EnumNetworks_FormatMessage, hr );
  1771. goto Error;
  1772. }
  1773. hr = THR( SendStatusReport( m_bstrNodeName,
  1774. TASKID_Major_Find_Devices,
  1775. TASKID_Minor_Only_One_Network,
  1776. 1,
  1777. 1,
  1778. 1,
  1779. S_FALSE,
  1780. bstrNotification,
  1781. NULL
  1782. ) );
  1783. TraceSysFreeString( bstrNotification );
  1784. bstrNotification = NULL;
  1785. if ( FAILED( hr ) )
  1786. {
  1787. goto Cleanup;
  1788. }
  1789. } // if: fewer than two networks found
  1790. hr = S_OK;
  1791. Cleanup:
  1792. hr = THR( SendStatusReport(
  1793. m_bstrNodeName
  1794. , TASKID_Major_Update_Progress
  1795. , TASKID_Major_Gather_Networks
  1796. , 0
  1797. , cTotalNetworksIn + 2
  1798. , cTotalNetworksIn + 2
  1799. , S_OK
  1800. , NULL
  1801. , NULL
  1802. ) );
  1803. TraceSysFreeString( bstrUID );
  1804. TraceSysFreeString( bstrName );
  1805. TraceSysFreeString( bstrNotification );
  1806. if ( pccniLocal != NULL )
  1807. {
  1808. pccniLocal->Release();
  1809. }
  1810. for( celt = 0; celt < 10; celt ++ )
  1811. {
  1812. if ( pccni[ celt ] != NULL )
  1813. {
  1814. pccni[ celt ]->Release();
  1815. }
  1816. } // for: celt
  1817. HRETURN( hr );
  1818. Error:
  1819. //
  1820. // Tell the UI layer we're done will gathering and what the resulting
  1821. // status was.
  1822. //
  1823. THR( HrSendStatusReport(
  1824. m_bstrNodeName
  1825. , TASKID_Major_Find_Devices
  1826. , TASKID_Minor_Gathering_Managed_Devices
  1827. , 0
  1828. , 2
  1829. , 2
  1830. , hr
  1831. , IDS_ERR_TGI_FAILED_TRY_TO_REANALYZE
  1832. , 0
  1833. ) );
  1834. goto Cleanup;
  1835. } //*** CTaskGatherInformation::HrGatherNetworks
  1836. //////////////////////////////////////////////////////////////////////////////
  1837. //
  1838. // HRESULT
  1839. // CTaskGatherInformation::HrSendStatusReport(
  1840. // LPCWSTR pcszNodeNameIn
  1841. // , CLSID clsidMajorIn
  1842. // , CLSID clsidMinorIn
  1843. // , ULONG ulMinIn
  1844. // , ULONG ulMaxIn
  1845. // , ULONG ulCurrentIn
  1846. // , HRESULT hrIn
  1847. // , int idsDescriptionIdIn
  1848. // , int idsReferenceIn
  1849. // )
  1850. //
  1851. //////////////////////////////////////////////////////////////////////////////
  1852. HRESULT
  1853. CTaskGatherInformation::HrSendStatusReport(
  1854. LPCWSTR pcszNodeNameIn
  1855. , CLSID clsidMajorIn
  1856. , CLSID clsidMinorIn
  1857. , ULONG ulMinIn
  1858. , ULONG ulMaxIn
  1859. , ULONG ulCurrentIn
  1860. , HRESULT hrIn
  1861. , int idsDescriptionIdIn
  1862. , int idsReferenceIdIn
  1863. )
  1864. {
  1865. TraceFunc( "" );
  1866. HRESULT hr = S_OK;
  1867. BSTR bstrDescription = NULL;
  1868. BSTR bstrReference = NULL;
  1869. hr = THR( HrLoadStringIntoBSTR( g_hInstance, idsDescriptionIdIn, &bstrDescription ) );
  1870. if ( FAILED( hr ) )
  1871. {
  1872. goto Cleanup;
  1873. } // if:
  1874. if ( idsReferenceIdIn != 0 )
  1875. {
  1876. hr = THR( HrLoadStringIntoBSTR( g_hInstance, idsReferenceIdIn, &bstrReference ) );
  1877. if ( FAILED( hr ) )
  1878. {
  1879. goto Cleanup;
  1880. } // if:
  1881. } // if: reference ID was specified
  1882. hr = THR( SendStatusReport( pcszNodeNameIn, clsidMajorIn, clsidMinorIn, ulMinIn, ulMaxIn, ulCurrentIn, hrIn, bstrDescription, bstrReference ) );
  1883. Cleanup:
  1884. TraceSysFreeString( bstrDescription );
  1885. TraceSysFreeString( bstrReference );
  1886. HRETURN( hr );
  1887. } //*** CTaskGatherInformation::HrSendStatusReport( idsDescriptionIn )
  1888. //////////////////////////////////////////////////////////////////////////////
  1889. //
  1890. // HRESULT
  1891. // CTaskGatherInformation::HrSendStatusReport(
  1892. // LPCWSTR pcszNodeNameIn
  1893. // , CLSID clsidMajorIn
  1894. // , CLSID clsidMinorIn
  1895. // , ULONG ulMinIn
  1896. // , ULONG ulMaxIn
  1897. // , ULONG ulCurrentIn
  1898. // , HRESULT hrIn
  1899. // , LPCWSTR pcszDescriptionIdIn
  1900. // , int idsReferenceIn
  1901. // )
  1902. //
  1903. //////////////////////////////////////////////////////////////////////////////
  1904. HRESULT
  1905. CTaskGatherInformation::HrSendStatusReport(
  1906. LPCWSTR pcszNodeNameIn
  1907. , CLSID clsidMajorIn
  1908. , CLSID clsidMinorIn
  1909. , ULONG ulMinIn
  1910. , ULONG ulMaxIn
  1911. , ULONG ulCurrentIn
  1912. , HRESULT hrIn
  1913. , LPCWSTR pcszDescriptionIdIn
  1914. , int idsReferenceIdIn
  1915. )
  1916. {
  1917. TraceFunc( "" );
  1918. HRESULT hr = S_OK;
  1919. BSTR bstrReference = NULL;
  1920. hr = THR( HrLoadStringIntoBSTR( g_hInstance, idsReferenceIdIn, &bstrReference ) );
  1921. if ( FAILED( hr ) )
  1922. {
  1923. goto Cleanup;
  1924. } // if:
  1925. hr = THR( SendStatusReport( pcszNodeNameIn, clsidMajorIn, clsidMinorIn, ulMinIn, ulMaxIn, ulCurrentIn, hrIn, pcszDescriptionIdIn, bstrReference ) );
  1926. Cleanup:
  1927. TraceSysFreeString( bstrReference );
  1928. HRETURN( hr );
  1929. } //*** CTaskGatherInformation::HrSendStatusReport( pcszDescription )
  1930. //****************************************************************************
  1931. //
  1932. // Static function implementations
  1933. //
  1934. //****************************************************************************
  1935. //////////////////////////////////////////////////////////////////////////////
  1936. //++
  1937. //
  1938. // HrTotalManagedResourceCount
  1939. //
  1940. // Description:
  1941. //
  1942. // Arguments:
  1943. // pResourceEnumIn -
  1944. // pNetworkEnumIn -
  1945. // pnCountOut -
  1946. //
  1947. // Return Values:
  1948. //
  1949. //--
  1950. //////////////////////////////////////////////////////////////////////////////
  1951. static
  1952. HRESULT
  1953. HrTotalManagedResourceCount(
  1954. IEnumClusCfgManagedResources * pResourceEnumIn
  1955. , IEnumClusCfgNetworks * pNetworkEnumIn
  1956. , DWORD * pnCountOut
  1957. )
  1958. {
  1959. TraceFunc( "" );
  1960. DWORD cResources = 0;
  1961. DWORD cNetworks = 0;
  1962. HRESULT hr = S_OK;
  1963. if ( ( pResourceEnumIn == NULL ) || ( pNetworkEnumIn == NULL ) || ( pnCountOut == NULL ) )
  1964. {
  1965. hr = THR( E_POINTER );
  1966. goto Cleanup;
  1967. }
  1968. //
  1969. // Ask the resource enumerator how many resources its collection has.
  1970. //
  1971. hr = THR(pResourceEnumIn->Count( &cResources ));
  1972. if ( FAILED( hr ) )
  1973. {
  1974. goto Cleanup;
  1975. }
  1976. //
  1977. // Ask the network enumerator how many networks its collection has.
  1978. //
  1979. hr = pNetworkEnumIn->Count( &cNetworks );
  1980. if ( FAILED( hr ) )
  1981. {
  1982. goto Cleanup;
  1983. }
  1984. *pnCountOut = cResources + cNetworks;
  1985. Cleanup:
  1986. HRETURN( hr );
  1987. } //*** HrTotalManagedResourceCount