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.

2166 lines
53 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CClusCfgClusterInfo.cpp
  7. //
  8. // Description:
  9. // This file contains the definition of the CClusCfgClusterInfo
  10. // class.
  11. //
  12. // The class CClusCfgClusterInfo is the representation of a
  13. // cluster. It implements the IClusCfgClusterInfo interface.
  14. //
  15. // Maintained By:
  16. // Galen Barbee (GalenB) 22-FEB-2000
  17. //
  18. //////////////////////////////////////////////////////////////////////////////
  19. //////////////////////////////////////////////////////////////////////////////
  20. // Include Files
  21. //////////////////////////////////////////////////////////////////////////////
  22. #include "Pch.h"
  23. #include <PropList.h>
  24. #include <ClusRtl.h>
  25. #include <windns.h>
  26. #include <commctrl.h>
  27. #include <ClusCfgPrivate.h>
  28. #include <ClusterUtils.h>
  29. #include "CClusCfgClusterInfo.h"
  30. //////////////////////////////////////////////////////////////////////////////
  31. // Constant Definitions
  32. //////////////////////////////////////////////////////////////////////////////
  33. DEFINE_THISCLASS( "CClusCfgClusterInfo" );
  34. //*************************************************************************//
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CClusCfgClusterInfo class
  37. /////////////////////////////////////////////////////////////////////////////
  38. //////////////////////////////////////////////////////////////////////////////
  39. //++
  40. //
  41. // CClusCfgClusterInfo::S_HrCreateInstance
  42. //
  43. // Description:
  44. // Create a CClusCfgClusterInfo instance.
  45. //
  46. // Arguments:
  47. // None.
  48. //
  49. // Return Values:
  50. // S_OK
  51. // Success.
  52. //
  53. // E_POINTER
  54. // A passed in argument is NULL.
  55. //
  56. // E_OUTOFMEMORY
  57. // Out of memory.
  58. //
  59. // Other HRESULT error.
  60. //
  61. //--
  62. //////////////////////////////////////////////////////////////////////////////
  63. HRESULT
  64. CClusCfgClusterInfo::S_HrCreateInstance(
  65. IUnknown ** ppunkOut
  66. )
  67. {
  68. TraceFunc( "" );
  69. HRESULT hr = S_OK;
  70. CClusCfgClusterInfo * pccci = NULL;
  71. if ( ppunkOut == NULL )
  72. {
  73. hr = THR( E_POINTER );
  74. goto Cleanup;
  75. } // if:
  76. pccci = new CClusCfgClusterInfo();
  77. if ( pccci == NULL )
  78. {
  79. hr = THR( E_OUTOFMEMORY );
  80. goto Cleanup;
  81. } // if: error allocating object
  82. hr = THR( pccci->HrInit() );
  83. if ( FAILED( hr ) )
  84. {
  85. goto Cleanup;
  86. } // if: HrInit() failed
  87. hr = THR( pccci->TypeSafeQI( IUnknown, ppunkOut ) );
  88. if ( FAILED( hr ) )
  89. {
  90. goto Cleanup;
  91. } // if: QI failed
  92. Cleanup:
  93. if ( pccci != NULL )
  94. {
  95. pccci->Release();
  96. } // if:
  97. if ( FAILED( hr ) )
  98. {
  99. LogMsg( L"[SRV] CClusCfgClusterInfo::S_HrCreateInstance() failed. (hr = %#08x)", hr );
  100. } // if:
  101. HRETURN( hr );
  102. } //*** CClusCfgClusterInfo::S_HrCreateInstance
  103. //////////////////////////////////////////////////////////////////////////////
  104. //++
  105. //
  106. // CClusCfgClusterInfo::CClusCfgClusterInfo
  107. //
  108. // Description:
  109. // Constructor of the CClusCfgClusterInfo class. This initializes
  110. // the m_cRef variable to 1 instead of 0 to account of possible
  111. // QueryInterface failure in DllGetClassObject.
  112. //
  113. // Arguments:
  114. // None.
  115. //
  116. // Return Value:
  117. // None.
  118. //
  119. // Remarks:
  120. // None.
  121. //
  122. //--
  123. //////////////////////////////////////////////////////////////////////////////
  124. CClusCfgClusterInfo::CClusCfgClusterInfo( void )
  125. : m_cRef( 1 )
  126. , m_lcid( LOCALE_NEUTRAL )
  127. {
  128. TraceFunc( "" );
  129. // Increment the count of components in memory so the DLL hosting this
  130. // object cannot be unloaded.
  131. InterlockedIncrement( &g_cObjects );
  132. Assert( m_picccCallback == NULL );
  133. Assert( m_bstrName == NULL );
  134. Assert( m_piccniNetwork == NULL );
  135. Assert( m_ulIPDottedQuad == 0 );
  136. Assert( m_ulSubnetDottedQuad == 0 );
  137. Assert( m_punkServiceAccountCredentials == NULL );
  138. Assert( m_pIWbemServices == NULL );
  139. Assert( m_ecmCommitChangesMode == cmUNKNOWN );
  140. Assert( m_bstrBindingString == NULL );
  141. TraceFuncExit();
  142. } //*** CClusCfgClusterInfo::CClusCfgClusterInfo
  143. //////////////////////////////////////////////////////////////////////////////
  144. //++
  145. //
  146. // CClusCfgClusterInfo::~CClusCfgClusterInfo
  147. //
  148. // Description:
  149. // Desstructor of the CClusCfgClusterInfo class.
  150. //
  151. // Arguments:
  152. // None.
  153. //
  154. // Return Value:
  155. // None.
  156. //
  157. // Remarks:
  158. // None.
  159. //
  160. //--
  161. //////////////////////////////////////////////////////////////////////////////
  162. CClusCfgClusterInfo::~CClusCfgClusterInfo( void )
  163. {
  164. TraceFunc( "" );
  165. if ( m_picccCallback != NULL )
  166. {
  167. m_picccCallback->Release();
  168. } // if:
  169. if ( m_piccniNetwork != NULL )
  170. {
  171. m_piccniNetwork->Release();
  172. } // if:
  173. if ( m_punkServiceAccountCredentials != NULL )
  174. {
  175. m_punkServiceAccountCredentials->Release();
  176. } // if:
  177. if ( m_pIWbemServices != NULL )
  178. {
  179. m_pIWbemServices->Release();
  180. } // if:
  181. TraceSysFreeString( m_bstrName );
  182. TraceSysFreeString( m_bstrBindingString );
  183. // There's going to be one less component in memory. Decrement component count.
  184. InterlockedDecrement( &g_cObjects );
  185. TraceFuncExit();
  186. } //*** CClusCfgClusterInfo::~CClusCfgClusterInfo
  187. //*************************************************************************//
  188. /////////////////////////////////////////////////////////////////////////////
  189. // CClusCfgClusterInfo -- IUknkown interface.
  190. /////////////////////////////////////////////////////////////////////////////
  191. //////////////////////////////////////////////////////////////////////////////
  192. //++
  193. //
  194. // CClusCfgClusterInfo::AddRef
  195. //
  196. // Description:
  197. // Increment the reference count of this object by one.
  198. //
  199. // Arguments:
  200. // None.
  201. //
  202. // Return Value:
  203. // The new reference count.
  204. //
  205. // Remarks:
  206. // None.
  207. //
  208. //--
  209. //////////////////////////////////////////////////////////////////////////////
  210. STDMETHODIMP_( ULONG )
  211. CClusCfgClusterInfo::AddRef( void )
  212. {
  213. TraceFunc( "[IUnknown]" );
  214. InterlockedIncrement( & m_cRef );
  215. CRETURN( m_cRef );
  216. } //*** CClusCfgClusterInfo::AddRef
  217. //////////////////////////////////////////////////////////////////////////////
  218. //++
  219. //
  220. // CClusCfgClusterInfo::Release
  221. //
  222. // Description:
  223. // Decrement the reference count of this object by one.
  224. //
  225. // Arguments:
  226. // None.
  227. //
  228. // Return Value:
  229. // The new reference count.
  230. //
  231. // Remarks:
  232. // None.
  233. //
  234. //--
  235. //////////////////////////////////////////////////////////////////////////////
  236. STDMETHODIMP_( ULONG )
  237. CClusCfgClusterInfo::Release( void )
  238. {
  239. TraceFunc( "[IUnknown]" );
  240. LONG cRef;
  241. cRef = InterlockedDecrement( &m_cRef );
  242. if ( cRef == 0 )
  243. {
  244. TraceDo( delete this );
  245. } // if: reference count equal to zero
  246. CRETURN( cRef );
  247. } //*** CClusCfgClusterInfo::Release
  248. //////////////////////////////////////////////////////////////////////////////
  249. //++
  250. //
  251. // CClusCfgClusterInfo::QueryInterface
  252. //
  253. // Description:
  254. // Query this object for the passed in interface.
  255. //
  256. // Arguments:
  257. // riidIn
  258. // Id of interface requested.
  259. //
  260. // ppvOut
  261. // Pointer to the requested interface.
  262. //
  263. // Return Value:
  264. // S_OK
  265. // If the interface is available on this object.
  266. //
  267. // E_NOINTERFACE
  268. // If the interface is not available.
  269. //
  270. // E_POINTER
  271. // ppvOut was NULL.
  272. //
  273. // Remarks:
  274. // None.
  275. //
  276. //--
  277. //////////////////////////////////////////////////////////////////////////////
  278. STDMETHODIMP
  279. CClusCfgClusterInfo::QueryInterface(
  280. REFIID riidIn
  281. , void ** ppvOut
  282. )
  283. {
  284. TraceQIFunc( riidIn, ppvOut );
  285. HRESULT hr = S_OK;
  286. //
  287. // Validate arguments.
  288. //
  289. Assert( ppvOut != NULL );
  290. if ( ppvOut == NULL )
  291. {
  292. hr = THR( E_POINTER );
  293. goto Cleanup;
  294. }
  295. //
  296. // Handle known interfaces.
  297. //
  298. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  299. {
  300. *ppvOut = static_cast< IClusCfgClusterInfo * >( this );
  301. } // if: IUnknown
  302. else if ( IsEqualIID( riidIn, IID_IClusCfgClusterInfo ) )
  303. {
  304. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgClusterInfo, this, 0 );
  305. } // else if: IClusCfgClusterInfo
  306. else if ( IsEqualIID( riidIn, IID_IClusCfgInitialize ) )
  307. {
  308. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 );
  309. } // else if: IClusCfgInitialize
  310. else if ( IsEqualIID( riidIn, IID_IClusCfgSetClusterNodeInfo ) )
  311. {
  312. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgSetClusterNodeInfo, this, 0 );
  313. } // else if: IClusCfgSetClusterNodeInfo
  314. else if ( IsEqualIID( riidIn, IID_IClusCfgWbemServices ) )
  315. {
  316. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgWbemServices, this, 0 );
  317. } // else if: IClusCfgWbemServices
  318. else if ( IsEqualIID( riidIn, IID_IClusCfgClusterInfoEx ) )
  319. {
  320. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgClusterInfoEx, this, 0 );
  321. } // else if: IClusCfgClusterInfoEx
  322. else
  323. {
  324. *ppvOut = NULL;
  325. hr = E_NOINTERFACE;
  326. } // else:
  327. //
  328. // Add a reference to the interface if successful.
  329. //
  330. if ( SUCCEEDED( hr ) )
  331. {
  332. ((IUnknown *) *ppvOut)->AddRef();
  333. } // if: success
  334. Cleanup:
  335. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  336. } //*** CClusCfgClusterInfo::QueryInterface
  337. //*************************************************************************//
  338. /////////////////////////////////////////////////////////////////////////////
  339. // CClusCfgClusterInfo -- IClusCfgWbemServices interface.
  340. /////////////////////////////////////////////////////////////////////////////
  341. //////////////////////////////////////////////////////////////////////////////
  342. //++
  343. //
  344. // CClusCfgClusterInfo::SetWbemServices
  345. //
  346. // Description:
  347. // Set the WBEM services provider.
  348. //
  349. // Arguments:
  350. // IN IWbemServices pIWbemServicesIn
  351. //
  352. // Return Value:
  353. // S_OK
  354. // Success
  355. //
  356. // E_POINTER
  357. // The pIWbemServicesIn param is NULL.
  358. //
  359. // Remarks:
  360. // None.
  361. //
  362. //--
  363. //////////////////////////////////////////////////////////////////////////////
  364. STDMETHODIMP
  365. CClusCfgClusterInfo::SetWbemServices(
  366. IWbemServices * pIWbemServicesIn
  367. )
  368. {
  369. TraceFunc( "[IClusCfgWbemServices]" );
  370. HRESULT hr = S_OK;
  371. if ( pIWbemServicesIn == NULL )
  372. {
  373. hr = THR( E_POINTER );
  374. STATUS_REPORT_REF( TASKID_Major_Establish_Connection, TASKID_Minor_SetWbemServices_Cluster, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  375. goto Cleanup;
  376. } // if:
  377. m_pIWbemServices = pIWbemServicesIn;
  378. m_pIWbemServices->AddRef();
  379. Cleanup:
  380. HRETURN( hr );
  381. } //*** CClusCfgClusterInfo::SetWbemServices
  382. //*************************************************************************//
  383. /////////////////////////////////////////////////////////////////////////////
  384. // CClusCfgClusterInfo -- IClusCfgInitialze interface.
  385. /////////////////////////////////////////////////////////////////////////////
  386. //////////////////////////////////////////////////////////////////////////////
  387. //++
  388. //
  389. // CClusCfgClusterInfo::Initialize
  390. //
  391. // Description:
  392. // Initialize this component.
  393. //
  394. // Arguments:
  395. // IN IUknown * punkCallbackIn
  396. //
  397. // IN LCID lcidIn
  398. //
  399. // Return Value:
  400. // S_OK
  401. // Success
  402. //
  403. // Remarks:
  404. // None.
  405. //
  406. //--
  407. //////////////////////////////////////////////////////////////////////////////
  408. STDMETHODIMP
  409. CClusCfgClusterInfo::Initialize(
  410. IUnknown * punkCallbackIn,
  411. LCID lcidIn
  412. )
  413. {
  414. TraceFunc( "[IClusCfgInitialize]" );
  415. HRESULT hr = S_OK;
  416. HRESULT hrTemp = S_OK;
  417. HCLUSTER hCluster = NULL;
  418. DWORD sc;
  419. DWORD dwState;
  420. BSTR bstrDomain = NULL;
  421. BSTR bstrClusterName = NULL;
  422. size_t cchName;
  423. size_t cchClusterName;
  424. size_t cchDomain;
  425. m_lcid = lcidIn;
  426. Assert( m_picccCallback == NULL );
  427. if ( punkCallbackIn == NULL )
  428. {
  429. hr = THR( E_POINTER );
  430. goto Cleanup;
  431. } // if:
  432. hr = THR( punkCallbackIn->TypeSafeQI( IClusCfgCallback, &m_picccCallback ) );
  433. if ( FAILED( hr ) )
  434. {
  435. goto Cleanup;
  436. } // if:
  437. if ( m_fIsClusterNode )
  438. {
  439. //
  440. // Get the cluster state of the node.
  441. // Ignore the case where the service does not exist so that
  442. // EvictCleanup can do its job.
  443. //
  444. sc = GetNodeClusterState( NULL, &dwState );
  445. if ( sc == ERROR_SERVICE_DOES_NOT_EXIST )
  446. {
  447. LOG_STATUS_REPORT( L"CClusCfgClusterInfo::Initialize() GetNodeClusterState() determined that the cluster service does not exist.", hr );
  448. }
  449. else if ( sc != ERROR_SUCCESS )
  450. {
  451. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  452. LOG_STATUS_REPORT( L"CClusCfgClusterInfo::Initialize() GetNodeClusterState() failed.", hr );
  453. goto Cleanup;
  454. } // if:
  455. Assert( ( dwState == ClusterStateRunning ) || ( dwState == ClusterStateNotRunning ) );
  456. if ( dwState == ClusterStateNotRunning )
  457. {
  458. //
  459. // Set hrTemp to S_FALSE so a warning is shown in the UI.
  460. //
  461. hrTemp = S_FALSE;
  462. STATUS_REPORT_REF( TASKID_Major_Establish_Connection, TASKID_Minor_Node_Down, IDS_ERROR_NODE_DOWN, IDS_ERROR_NODE_DOWN_REF, hrTemp );
  463. LogMsg( L"[SRV] The cluster service is down on this node." );
  464. //
  465. // Set hrTemp to HR_S_RPC_S_CLUSTER_NODE_DOWN so we can return this later.
  466. //
  467. hrTemp = HR_S_RPC_S_CLUSTER_NODE_DOWN;
  468. goto ClusterNodeDown;
  469. } // if:
  470. hCluster = OpenCluster( NULL );
  471. if ( hCluster == NULL )
  472. {
  473. sc = TW32( GetLastError() );
  474. hr = HRESULT_FROM_WIN32( sc );
  475. LOG_STATUS_REPORT( L"CClusCfgClusterInfo::Initialize() OpenCluster() failed.", hr );
  476. goto Cleanup;
  477. } // if:
  478. hr = THR( HrGetClusterInformation( hCluster, &bstrClusterName, NULL ) );
  479. if ( FAILED( hr ) )
  480. {
  481. goto Cleanup;
  482. } // if:
  483. hr = THR( HrGetComputerName(
  484. ComputerNamePhysicalDnsDomain
  485. , &bstrDomain
  486. , FALSE // fBestEffortIn
  487. ) );
  488. if ( FAILED( hr ) )
  489. {
  490. goto Cleanup;
  491. } // if:
  492. cchClusterName = wcslen( bstrClusterName );
  493. cchDomain = wcslen( bstrDomain );
  494. cchName = cchClusterName + cchDomain + 2; // '.' + UNICODE_NULL
  495. TraceSysFreeString( m_bstrName );
  496. m_bstrName = TraceSysAllocStringLen( NULL, (UINT) cchName );
  497. if ( m_bstrName == NULL )
  498. {
  499. hr = THR( E_OUTOFMEMORY );
  500. STATUS_REPORT_REF( TASKID_Major_Establish_Connection, TASKID_Minor_Initialize, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
  501. goto Cleanup;
  502. } // if:
  503. hr = THR( StringCchCopyW( m_bstrName, cchName, bstrClusterName ) );
  504. if ( FAILED( hr ) )
  505. {
  506. goto Cleanup;
  507. } // if:
  508. hr = THR( StringCchCatW( m_bstrName, cchName, L"." ) );
  509. if ( FAILED( hr ) )
  510. {
  511. goto Cleanup;
  512. } // if:
  513. hr = THR( StringCchCatW( m_bstrName, cchName, bstrDomain ) );
  514. if ( FAILED( hr ) )
  515. {
  516. goto Cleanup;
  517. } // if:
  518. hr = THR( HrLoadNetworkInfo( hCluster ) );
  519. if ( FAILED( hr ) )
  520. {
  521. goto Cleanup;
  522. } // if:
  523. ClusterNodeDown:
  524. hr = STHR( HrLoadCredentials() );
  525. if ( SUCCEEDED( hr ) )
  526. {
  527. //
  528. // If successful then use hrTemp since it may contain a more important status code.
  529. //
  530. hr = hrTemp;
  531. LogMsg( L"[SRV] CClusCfgClusterInfo::Initialize() returning (hr=%#08x)", hr );
  532. } // if:
  533. } // if:
  534. Cleanup:
  535. TraceSysFreeString( bstrDomain );
  536. TraceSysFreeString( bstrClusterName );
  537. if ( hCluster != NULL )
  538. {
  539. CloseCluster( hCluster );
  540. } // if:
  541. HRETURN( hr );
  542. } //*** CClusCfgClusterInfo::Initialize
  543. //*************************************************************************//
  544. /////////////////////////////////////////////////////////////////////////////
  545. // CClusCfgClusterInfo -- IClusCfgClusterInfo interface.
  546. /////////////////////////////////////////////////////////////////////////////
  547. //////////////////////////////////////////////////////////////////////////////
  548. //++
  549. //
  550. // CClusCfgClusterInfo::GetCommitMode
  551. //
  552. // Description:
  553. // Get the mode of processing for this node when commit changes is
  554. // called.
  555. //
  556. // Arguments:
  557. //
  558. // Return Value:
  559. // S_OK
  560. // Success.
  561. //
  562. // E_POINTER
  563. // pecmCurrentModeOut is NULL.
  564. //
  565. // Other Win32 error as HRESULT if a failure occurs.
  566. //
  567. // Remarks:
  568. // None.
  569. //
  570. //--
  571. //////////////////////////////////////////////////////////////////////////////
  572. STDMETHODIMP
  573. CClusCfgClusterInfo::GetCommitMode(
  574. ECommitMode * pecmCurrentModeOut
  575. )
  576. {
  577. TraceFunc( "[IClusCfgClusterInfo]" );
  578. HRESULT hr = S_OK;
  579. if ( pecmCurrentModeOut == NULL )
  580. {
  581. hr = THR( E_POINTER );
  582. goto Cleanup;
  583. } // if:
  584. *pecmCurrentModeOut = m_ecmCommitChangesMode;
  585. Cleanup:
  586. HRETURN( hr );
  587. } //*** CClusCfgClusterInfo::GetCommitMode
  588. //////////////////////////////////////////////////////////////////////////////
  589. //++
  590. //
  591. // CClusCfgClusterInfo::SetCommitMode
  592. //
  593. // Description:
  594. //
  595. // Arguments:
  596. //
  597. // Return Value:
  598. //
  599. // Remarks:
  600. // None.
  601. //
  602. //--
  603. //////////////////////////////////////////////////////////////////////////////
  604. STDMETHODIMP
  605. CClusCfgClusterInfo::SetCommitMode(
  606. ECommitMode ecmCurrentModeIn
  607. )
  608. {
  609. TraceFunc( "[IClusCfgClusterInfo]" );
  610. HRESULT hr = S_OK;
  611. m_ecmCommitChangesMode = ecmCurrentModeIn;
  612. HRETURN( hr );
  613. } //*** CClusCfgClusterInfo::SetCommitMode
  614. //////////////////////////////////////////////////////////////////////////////
  615. //++
  616. //
  617. // CClusCfgClusterInfo::GetName
  618. //
  619. // Description:
  620. //
  621. // Arguments:
  622. //
  623. // Return Value:
  624. //
  625. // Remarks:
  626. // None.
  627. //
  628. //--
  629. //////////////////////////////////////////////////////////////////////////////
  630. STDMETHODIMP
  631. CClusCfgClusterInfo::GetName(
  632. BSTR * pbstrNameOut
  633. )
  634. {
  635. TraceFunc( "[IClusCfgClusterInfo]" );
  636. HRESULT hr = S_OK;
  637. if ( pbstrNameOut == NULL )
  638. {
  639. hr = THR( E_POINTER );
  640. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_ClusterInfo_GetName_Pointer, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  641. goto Cleanup;
  642. } // if:
  643. if ( m_bstrName == NULL )
  644. {
  645. hr = HRESULT_FROM_WIN32( TW32( ERROR_NOT_FOUND ) );
  646. STATUS_REPORT_REF(
  647. TASKID_Major_Find_Devices
  648. , TASKID_Minor_Get_Cluster_Name
  649. , IDS_ERROR_CLUSTER_NAME_NOT_FOUND
  650. , IDS_ERROR_CLUSTER_NAME_NOT_FOUND_REF
  651. , hr
  652. );
  653. goto Cleanup;
  654. } // if:
  655. *pbstrNameOut = SysAllocString( m_bstrName );
  656. if ( *pbstrNameOut == NULL )
  657. {
  658. hr = THR( E_OUTOFMEMORY );
  659. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_GetName_Memory, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
  660. } // if:
  661. Cleanup:
  662. HRETURN( hr );
  663. } //*** CClusCfgClusterInfo::GetName
  664. //////////////////////////////////////////////////////////////////////////////
  665. //++
  666. //
  667. // CClusCfgClusterInfo::SetName
  668. //
  669. // Description:
  670. //
  671. // Arguments:
  672. //
  673. // Return Value:
  674. //
  675. // Remarks:
  676. // None.
  677. //
  678. //--
  679. //////////////////////////////////////////////////////////////////////////////
  680. STDMETHODIMP
  681. CClusCfgClusterInfo::SetName(
  682. LPCWSTR pcszNameIn
  683. )
  684. {
  685. TraceFunc1( "[IClusCfgClusterInfo] pcszNameIn = '%ls'", pcszNameIn == NULL ? L"<null>" : pcszNameIn );
  686. HRESULT hr;
  687. if ( pcszNameIn == NULL )
  688. {
  689. hr = THR( E_INVALIDARG );
  690. goto Cleanup;
  691. }
  692. TraceSysFreeString( m_bstrName );
  693. m_bstrName = NULL;
  694. m_bstrName = TraceSysAllocString( pcszNameIn );
  695. if ( m_bstrName == NULL )
  696. {
  697. hr = THR( E_OUTOFMEMORY );
  698. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_SetName_Cluster, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
  699. goto Cleanup;
  700. } // if:
  701. hr = S_OK;
  702. Cleanup:
  703. HRETURN( hr );
  704. } //*** CClusCfgClusterInfo::SetName
  705. //////////////////////////////////////////////////////////////////////////////
  706. //++
  707. //
  708. // CClusCfgClusterInfo::GetIPAddress
  709. //
  710. // Description:
  711. //
  712. // Arguments:
  713. //
  714. // Return Value:
  715. //
  716. // Remarks:
  717. // None.
  718. //
  719. //--
  720. //////////////////////////////////////////////////////////////////////////////
  721. STDMETHODIMP
  722. CClusCfgClusterInfo::GetIPAddress(
  723. ULONG * pulDottedQuadOut
  724. )
  725. {
  726. TraceFunc( "[IClusCfgClusterInfo]" );
  727. HRESULT hr = S_OK;
  728. if ( pulDottedQuadOut == NULL )
  729. {
  730. hr = THR( E_POINTER );
  731. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_GetIPAddress, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  732. goto Cleanup;
  733. } // if:
  734. if ( m_ulIPDottedQuad == 0 )
  735. {
  736. hr = HRESULT_FROM_WIN32( TW32( ERROR_NOT_FOUND ) );
  737. STATUS_REPORT_REF(
  738. TASKID_Major_Find_Devices
  739. , TASKID_Minor_Get_Cluster_IP_Address
  740. , IDS_ERROR_CLUSTER_IP_ADDRESS_NOT_FOUND
  741. , IDS_ERROR_CLUSTER_IP_ADDRESS_NOT_FOUND_REF
  742. , hr
  743. );
  744. goto Cleanup;
  745. } // if:
  746. *pulDottedQuadOut = m_ulIPDottedQuad;
  747. Cleanup:
  748. HRETURN( hr );
  749. } //*** CClusCfgClusterInfo::GetIPAddress
  750. //////////////////////////////////////////////////////////////////////////////
  751. //++
  752. //
  753. // CClusCfgClusterInfo::SetIPAddress
  754. //
  755. // Description:
  756. //
  757. // Arguments:
  758. //
  759. // Return Value:
  760. //
  761. // Remarks:
  762. // None.
  763. //
  764. //--
  765. //////////////////////////////////////////////////////////////////////////////
  766. STDMETHODIMP
  767. CClusCfgClusterInfo::SetIPAddress(
  768. ULONG ulDottedQuadIn
  769. )
  770. {
  771. TraceFunc( "[IClusCfgClusterInfo]" );
  772. HRESULT hr = S_OK;
  773. m_ulIPDottedQuad = ulDottedQuadIn;
  774. HRETURN( hr );
  775. } //*** CClusCfgClusterInfo::SetIPAddress
  776. //////////////////////////////////////////////////////////////////////////////
  777. //++
  778. //
  779. // CClusCfgClusterInfo::GetSubnetMask
  780. //
  781. // Description:
  782. //
  783. // Arguments:
  784. //
  785. // Return Value:
  786. //
  787. // Remarks:
  788. // None.
  789. //
  790. //--
  791. //////////////////////////////////////////////////////////////////////////////
  792. STDMETHODIMP
  793. CClusCfgClusterInfo::GetSubnetMask(
  794. ULONG * pulDottedQuadOut
  795. )
  796. {
  797. TraceFunc( "[IClusCfgClusterInfo]" );
  798. HRESULT hr = S_OK;
  799. if ( pulDottedQuadOut == NULL )
  800. {
  801. hr = THR( E_POINTER );
  802. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_ClusterInfo_GetSubnetMask, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  803. goto Cleanup;
  804. } // if:
  805. if ( m_ulSubnetDottedQuad == 0 )
  806. {
  807. hr = HRESULT_FROM_WIN32( TW32( ERROR_NOT_FOUND ) );
  808. STATUS_REPORT_REF(
  809. TASKID_Major_Find_Devices
  810. , TASKID_Minor_Get_Cluster_IP_Subnet
  811. , IDS_ERROR_CLUSTER_IP_SUBNET_NOT_FOUND
  812. , IDS_ERROR_CLUSTER_IP_SUBNET_NOT_FOUND_REF
  813. , hr
  814. );
  815. goto Cleanup;
  816. } // if:
  817. *pulDottedQuadOut = m_ulSubnetDottedQuad;
  818. Cleanup:
  819. HRETURN( hr );
  820. } //*** CClusCfgClusterInfo::GetSubnetMask
  821. //////////////////////////////////////////////////////////////////////////////
  822. //++
  823. //
  824. // CClusCfgClusterInfo::SetSubnetMask
  825. //
  826. // Description:
  827. //
  828. // Arguments:
  829. //
  830. // Return Value:
  831. //
  832. // Remarks:
  833. // None.
  834. //
  835. //--
  836. //////////////////////////////////////////////////////////////////////////////
  837. STDMETHODIMP
  838. CClusCfgClusterInfo::SetSubnetMask(
  839. ULONG ulDottedQuadIn
  840. )
  841. {
  842. TraceFunc( "[IClusCfgClusterInfo]" );
  843. HRESULT hr = S_OK;
  844. m_ulSubnetDottedQuad = ulDottedQuadIn;
  845. HRETURN( hr );
  846. } //*** CClusCfgClusterInfo::SetSubnetMask
  847. //////////////////////////////////////////////////////////////////////////////
  848. //++
  849. //
  850. // CClusCfgClusterInfo::GetNetworkInfo
  851. //
  852. // Description:
  853. //
  854. // Arguments:
  855. //
  856. // Return Value:
  857. //
  858. // Remarks:
  859. // None.
  860. //
  861. //--
  862. //////////////////////////////////////////////////////////////////////////////
  863. STDMETHODIMP
  864. CClusCfgClusterInfo::GetNetworkInfo(
  865. IClusCfgNetworkInfo ** ppiccniOut
  866. )
  867. {
  868. TraceFunc( "[IClusCfgClusterInfo]" );
  869. Assert( m_piccniNetwork != NULL );
  870. HRESULT hr = S_OK;
  871. if ( ppiccniOut == NULL )
  872. {
  873. hr = THR( E_POINTER );
  874. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_GetNetworkInfo, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  875. goto Cleanup;
  876. } // if:
  877. if ( m_piccniNetwork == NULL )
  878. {
  879. hr = HRESULT_FROM_WIN32( TW32( ERROR_NOT_FOUND ) );
  880. STATUS_REPORT_REF(
  881. TASKID_Major_Find_Devices
  882. , TASKID_Minor_Get_Cluster_Networks
  883. , IDS_ERROR_CLUSTER_NETWORKS_NOT_FOUND
  884. , IDS_ERROR_CLUSTER_NETWORKS_NOT_FOUND_REF
  885. , hr
  886. );
  887. goto Cleanup;
  888. } // if:
  889. *ppiccniOut = TraceInterface( L"CClusCfgNetworkInfo", IClusCfgNetworkInfo, m_piccniNetwork, 0 );
  890. (*ppiccniOut)->AddRef();
  891. Cleanup:
  892. HRETURN( hr );
  893. } //*** CClusCfgClusterInfo::GetNetworkInfo
  894. //////////////////////////////////////////////////////////////////////////////
  895. //++
  896. //
  897. // CClusCfgClusterInfo::SetNetworkInfo
  898. //
  899. // Description:
  900. //
  901. // Arguments:
  902. //
  903. // Return Value:
  904. //
  905. // Remarks:
  906. // None.
  907. //
  908. //--
  909. //////////////////////////////////////////////////////////////////////////////
  910. STDMETHODIMP
  911. CClusCfgClusterInfo::SetNetworkInfo(
  912. IClusCfgNetworkInfo * piccniIn
  913. )
  914. {
  915. TraceFunc( "[IClusCfgClusterInfo]" );
  916. Assert( piccniIn != NULL );
  917. HRESULT hr = S_OK;
  918. if ( piccniIn == NULL )
  919. {
  920. hr = THR( E_INVALIDARG );
  921. goto Cleanup;
  922. } // if:
  923. if ( m_piccniNetwork != NULL )
  924. {
  925. m_piccniNetwork->Release();
  926. } // if:
  927. m_piccniNetwork = piccniIn;
  928. m_piccniNetwork->AddRef();
  929. Cleanup:
  930. HRETURN( hr );
  931. } //*** CClusCfgClusterInfo::SetNetworkInfo
  932. //////////////////////////////////////////////////////////////////////////////
  933. //++
  934. //
  935. // CClusCfgClusterInfo::GetClusterServiceAccountCredentials
  936. //
  937. // Description:
  938. //
  939. // Arguments:
  940. //
  941. // Return Value:
  942. //
  943. // Remarks:
  944. // None.
  945. //
  946. //--
  947. //////////////////////////////////////////////////////////////////////////////
  948. STDMETHODIMP
  949. CClusCfgClusterInfo::GetClusterServiceAccountCredentials(
  950. IClusCfgCredentials ** ppicccCredentialsOut
  951. )
  952. {
  953. TraceFunc( "[IClusCfgClusterInfo]" );
  954. HRESULT hr;
  955. if ( ppicccCredentialsOut == NULL )
  956. {
  957. hr = THR( E_POINTER );
  958. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_GetClusterServiceAccountCredentials, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  959. goto Cleanup;
  960. } // if:
  961. if ( m_punkServiceAccountCredentials != NULL )
  962. {
  963. hr = S_OK;
  964. LOG_STATUS_REPORT( L"CClusCfgClusterInfo::GetClusterServiceAccountCredentials() skipping object creation.", hr );
  965. goto SkipCreate;
  966. } // if:
  967. hr = THR( HrCoCreateInternalInstance(
  968. CLSID_ClusCfgCredentials
  969. , NULL
  970. , CLSCTX_INPROC_SERVER
  971. , IID_IUnknown
  972. , reinterpret_cast< void ** >( &m_punkServiceAccountCredentials )
  973. ) );
  974. if ( FAILED( hr ) )
  975. {
  976. goto Cleanup;
  977. } // if:
  978. m_punkServiceAccountCredentials = TraceInterface( L"CClusCfgCredentials", IUnknown, m_punkServiceAccountCredentials, 1 );
  979. hr = THR( HrSetInitialize( m_punkServiceAccountCredentials, m_picccCallback, m_lcid ) );
  980. if ( FAILED( hr ) )
  981. {
  982. goto Cleanup;
  983. } // if:
  984. hr = THR( HrSetWbemServices( m_punkServiceAccountCredentials, NULL ) );
  985. SkipCreate:
  986. if ( SUCCEEDED( hr ) )
  987. {
  988. Assert( m_punkServiceAccountCredentials != NULL );
  989. hr = THR( m_punkServiceAccountCredentials->TypeSafeQI( IClusCfgCredentials, ppicccCredentialsOut ) );
  990. } // if:
  991. Cleanup:
  992. HRETURN( hr );
  993. } //*** CClusCfgClusterInfo::GetClusterServiceAccountCredentials
  994. //////////////////////////////////////////////////////////////////////////////
  995. //++
  996. //
  997. // CClusCfgClusterInfo::GetBindingString
  998. //
  999. // Description:
  1000. // Get the binding string for this cluster.
  1001. //
  1002. // Arguments:
  1003. //
  1004. // Return Value:
  1005. //
  1006. // Remarks:
  1007. // None.
  1008. //
  1009. //--
  1010. //////////////////////////////////////////////////////////////////////////////
  1011. STDMETHODIMP
  1012. CClusCfgClusterInfo::GetBindingString(
  1013. BSTR * pbstrBindingStringOut
  1014. )
  1015. {
  1016. TraceFunc( "[IClusCfgClusterInfo]" );
  1017. HRESULT hr = S_OK;
  1018. if ( pbstrBindingStringOut == NULL )
  1019. {
  1020. hr = THR( E_POINTER );
  1021. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_ClusterInfo_GetBindingString_Pointer, IDS_ERROR_NULL_POINTER, IDS_ERROR_NULL_POINTER_REF, hr );
  1022. goto Cleanup;
  1023. } // if:
  1024. if ( m_bstrBindingString == NULL )
  1025. {
  1026. hr = S_FALSE;
  1027. LOG_STATUS_REPORT_MINOR(
  1028. TASKID_Minor_GetBindingString_Binding_String_NULL
  1029. , L"The cluster binding string is empty. If we are adding nodes then this is not correct!"
  1030. , hr );
  1031. goto Cleanup;
  1032. } // if:
  1033. *pbstrBindingStringOut = SysAllocString( m_bstrBindingString );
  1034. if ( *pbstrBindingStringOut == NULL )
  1035. {
  1036. hr = THR( E_OUTOFMEMORY );
  1037. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_GetBindingString_Memory, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
  1038. } // if:
  1039. Cleanup:
  1040. HRETURN( hr );
  1041. } //*** CClusCfgClusterInfo::GetBindingString
  1042. //////////////////////////////////////////////////////////////////////////////
  1043. //++
  1044. //
  1045. // CClusCfgClusterInfo::SetBindingString
  1046. //
  1047. // Description:
  1048. // Set the binding string of this cluster.
  1049. //
  1050. // Arguments:
  1051. //
  1052. // Return Value:
  1053. //
  1054. // Remarks:
  1055. // None.
  1056. //
  1057. //--
  1058. //////////////////////////////////////////////////////////////////////////////
  1059. STDMETHODIMP
  1060. CClusCfgClusterInfo::SetBindingString(
  1061. LPCWSTR pcszBindingStringIn
  1062. )
  1063. {
  1064. TraceFunc1( "[IClusCfgClusterInfo] pcszBindingStringIn = '%ls'", pcszBindingStringIn == NULL ? L"<null>" : pcszBindingStringIn );
  1065. HRESULT hr = S_OK;
  1066. BSTR bstr = NULL;
  1067. //
  1068. // When creating a cluster there is no cluster binding string. Therefore it is reasonable
  1069. // to accept a NULL string as the passed in parameter.
  1070. //
  1071. if ( pcszBindingStringIn == NULL )
  1072. {
  1073. hr = S_FALSE;
  1074. TraceSysFreeString( m_bstrBindingString );
  1075. m_bstrBindingString = NULL;
  1076. goto Cleanup;
  1077. } // if:
  1078. bstr = TraceSysAllocString( pcszBindingStringIn );
  1079. if ( bstr == NULL )
  1080. {
  1081. hr = THR( E_OUTOFMEMORY );
  1082. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_SetBindingString_Cluster, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
  1083. goto Cleanup;
  1084. } // if:
  1085. TraceSysFreeString( m_bstrBindingString );
  1086. m_bstrBindingString = bstr;
  1087. Cleanup:
  1088. HRETURN( hr );
  1089. } //*** CClusCfgClusterInfo::SetBindingString
  1090. //////////////////////////////////////////////////////////////////////////////
  1091. //++
  1092. //
  1093. // CClusCfgClusterInfo::GetMaxNodeCount
  1094. //
  1095. // Description:
  1096. // Get the maximum number of nodes supported in this cluster.
  1097. //
  1098. // Arguments:
  1099. // pcMaxNodesOut
  1100. //
  1101. // Return Value:
  1102. // S_OK
  1103. // Success;
  1104. //
  1105. // E_POINTER
  1106. // pcMaxNodesOut is NULL.
  1107. //
  1108. // Other HRESULT errors.
  1109. //
  1110. //--
  1111. //////////////////////////////////////////////////////////////////////////////
  1112. STDMETHODIMP
  1113. CClusCfgClusterInfo::GetMaxNodeCount(
  1114. DWORD * pcMaxNodesOut
  1115. )
  1116. {
  1117. TraceFunc( "[IClusCfgClusterInfo]" );
  1118. HRETURN( STHR( HrGetMaxNodeCount( pcMaxNodesOut ) ) );
  1119. } //*** CClusCfgClusterInfo::GetMaxNodeCount
  1120. //*************************************************************************//
  1121. /////////////////////////////////////////////////////////////////////////////
  1122. // CClusCfgClusterInfo class -- IClusCfgSetClusterNodeInfo Interfaces.
  1123. /////////////////////////////////////////////////////////////////////////////
  1124. //////////////////////////////////////////////////////////////////////////////
  1125. //++
  1126. //
  1127. // CClusCfgClusterInfo::SetClusterNodeInfo
  1128. //
  1129. // Description:
  1130. // Suck some info off of the passed in node info object.
  1131. //
  1132. // Arguments:
  1133. // None.
  1134. //
  1135. // Return Value:
  1136. //
  1137. //
  1138. // Remarks:
  1139. // None.
  1140. //
  1141. //--
  1142. //////////////////////////////////////////////////////////////////////////////
  1143. STDMETHODIMP
  1144. CClusCfgClusterInfo::SetClusterNodeInfo(
  1145. IClusCfgNodeInfo * pNodeInfoIn
  1146. )
  1147. {
  1148. TraceFunc( "[IClusCfgClusterInfo]" );
  1149. Assert( pNodeInfoIn != NULL );
  1150. HRESULT hr = S_FALSE;
  1151. if ( pNodeInfoIn == NULL )
  1152. {
  1153. hr = THR( E_INVALIDARG );
  1154. goto Cleanup;
  1155. } // if:
  1156. hr = STHR( pNodeInfoIn->IsMemberOfCluster() );
  1157. if ( hr == S_OK )
  1158. {
  1159. m_fIsClusterNode = true;
  1160. } // if:
  1161. else if ( hr == S_FALSE )
  1162. {
  1163. m_fIsClusterNode = false;
  1164. hr = S_OK;
  1165. } // else if:
  1166. Cleanup:
  1167. HRETURN( hr );
  1168. } //*** CClusCfgClusterInfo::SetClusterNodeInfo
  1169. //*************************************************************************//
  1170. /////////////////////////////////////////////////////////////////////////////
  1171. // CClusCfgClusterInfo class -- IClusCfgClusterInfoEx Interfaces.
  1172. /////////////////////////////////////////////////////////////////////////////
  1173. //////////////////////////////////////////////////////////////////////////////
  1174. //++
  1175. //
  1176. // CClusCfgClusterInfo::CheckJoiningNodeVersion
  1177. //
  1178. // Description:
  1179. // Check a joining node's version information against that of the cluster.
  1180. //
  1181. // Arguments:
  1182. // dwNodeHighestVersionIn
  1183. // dwNodeLowestVersionIn
  1184. //
  1185. // Return Value:
  1186. // S_OK
  1187. // The joining node is compatible.
  1188. //
  1189. // HRESULT_FROM_WIN32( ERROR_CLUSTER_INCOMPATIBLE_VERSIONS )
  1190. // The joining node is NOT compatible.
  1191. //
  1192. // Other HRESULT errors.
  1193. //
  1194. // Remarks:
  1195. //
  1196. // Get and verify the sponsor version
  1197. //
  1198. //
  1199. // From Whistler onwards, CsRpcGetJoinVersionData() will return a failure code in its last parameter
  1200. // if the version of this node is not compatible with the sponsor version. Prior to this, the last
  1201. // parameter always contained a success value and the cluster versions had to be compared subsequent to this
  1202. // call. This will, however, still have to be done as long as interoperability with Win2K
  1203. // is a requirement, since Win2K sponsors do not return an error in the last parameter.
  1204. //
  1205. //--
  1206. //////////////////////////////////////////////////////////////////////////////
  1207. STDMETHODIMP
  1208. CClusCfgClusterInfo::CheckJoiningNodeVersion(
  1209. DWORD dwNodeHighestVersionIn
  1210. , DWORD dwNodeLowestVersionIn
  1211. )
  1212. {
  1213. TraceFunc( "[IClusCfgClusterInfoEx]" );
  1214. HRESULT hr = S_OK;
  1215. hr = THR( HrCheckJoiningNodeVersion(
  1216. NULL
  1217. , dwNodeHighestVersionIn
  1218. , dwNodeLowestVersionIn
  1219. , m_picccCallback
  1220. ) );
  1221. HRETURN( hr );
  1222. } //*** CClusCfgClusterInfo::CheckJoiningNodeVersion
  1223. //////////////////////////////////////////////////////////////////////////////
  1224. //++
  1225. //
  1226. // CClusCfgClusterInfo::GetNodeNames
  1227. //
  1228. // Description:
  1229. // Retrieve the names of the nodes currently in the cluster.
  1230. //
  1231. // Parameters:
  1232. // pnCountOut
  1233. // On success, *pnCountOut returns the number of nodes in the cluster.
  1234. //
  1235. // prgbstrNodeNamesOut
  1236. // On success, an array of BSTRs containing the node names.
  1237. // The caller must free each BSTR with SysFreeString, and free
  1238. // the array with CoTaskMemFree.
  1239. //
  1240. // Return Values:
  1241. // S_OK
  1242. // The out parameters contain valid information and the caller
  1243. // must free the array and the BSTRs it contains.
  1244. //
  1245. // E_OUTOFMEMORY, and other failures are possible.
  1246. //
  1247. //--
  1248. //////////////////////////////////////////////////////////////////////////////
  1249. STDMETHODIMP
  1250. CClusCfgClusterInfo::GetNodeNames(
  1251. long * pnCountOut
  1252. , BSTR ** prgbstrNodeNamesOut
  1253. )
  1254. {
  1255. TraceFunc( "[IClusCfgClusterInfoEx]" );
  1256. HRESULT hr = S_OK;
  1257. HCLUSTER hCluster = NULL;
  1258. hCluster = OpenCluster( NULL );
  1259. if ( hCluster == NULL )
  1260. {
  1261. DWORD scLastError = TW32( GetLastError() );
  1262. hr = HRESULT_FROM_WIN32( scLastError );
  1263. goto Cleanup;
  1264. } // if
  1265. hr = THR( HrGetNodeNames(
  1266. hCluster
  1267. , pnCountOut
  1268. , prgbstrNodeNamesOut
  1269. ) );
  1270. if ( FAILED( hr ) )
  1271. {
  1272. goto Cleanup;
  1273. } // if:
  1274. Cleanup:
  1275. if ( hCluster != NULL )
  1276. {
  1277. CloseCluster( hCluster );
  1278. } // if
  1279. HRETURN( hr );
  1280. } //*** CClusCfgClusterInfo::GetNodeNames
  1281. //*************************************************************************//
  1282. /////////////////////////////////////////////////////////////////////////////
  1283. // CClusCfgClusterInfo class -- Private Methods.
  1284. /////////////////////////////////////////////////////////////////////////////
  1285. //////////////////////////////////////////////////////////////////////////////
  1286. //++
  1287. //
  1288. // CClusCfgClusterInfo::HrInit
  1289. //
  1290. // Description:
  1291. // Initialize this component.
  1292. //
  1293. // Arguments:
  1294. // None.
  1295. //
  1296. // Return Value:
  1297. //
  1298. //
  1299. // Remarks:
  1300. // None.
  1301. //
  1302. //--
  1303. //////////////////////////////////////////////////////////////////////////////
  1304. HRESULT
  1305. CClusCfgClusterInfo::HrInit( void )
  1306. {
  1307. TraceFunc( "" );
  1308. HRESULT hr = S_OK;
  1309. // IUnknown
  1310. Assert( m_cRef == 1 );
  1311. m_bstrName = TraceSysAllocString( L"\0" );
  1312. if ( m_bstrName == NULL )
  1313. {
  1314. hr = THR( E_OUTOFMEMORY );
  1315. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrInit, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
  1316. } // if:
  1317. HRETURN( hr );
  1318. } //*** CClusCfgClusterInfo::HrInit
  1319. //////////////////////////////////////////////////////////////////////////////
  1320. //++
  1321. //
  1322. // CClusCfgClusterInfo::HrLoadNetworkInfo
  1323. //
  1324. // Description:
  1325. // Load the cluster network info...
  1326. //
  1327. // Arguments:
  1328. //
  1329. //
  1330. // Return Value:
  1331. //
  1332. //
  1333. // Remarks:
  1334. // None.
  1335. //
  1336. //--
  1337. //////////////////////////////////////////////////////////////////////////////
  1338. HRESULT
  1339. CClusCfgClusterInfo::HrLoadNetworkInfo(
  1340. HCLUSTER hClusterIn
  1341. )
  1342. {
  1343. TraceFunc( "" );
  1344. Assert( hClusterIn != NULL );
  1345. HRESULT hr = S_OK;
  1346. DWORD sc;
  1347. HRESOURCE hIPAddress = NULL;
  1348. sc = TW32( ResUtilGetCoreClusterResources( hClusterIn, NULL, &hIPAddress, NULL ) );
  1349. if ( sc != ERROR_SUCCESS )
  1350. {
  1351. hr = HRESULT_FROM_WIN32( sc );
  1352. goto Cleanup;
  1353. } // if:
  1354. Assert( hIPAddress != NULL );
  1355. hr = THR( HrGetIPAddressInfo( hIPAddress ) );
  1356. if ( FAILED( hr ) )
  1357. {
  1358. goto Cleanup;
  1359. } // if:
  1360. Cleanup:
  1361. LOG_STATUS_REPORT_MINOR( TASKID_Minor_Server_LoadNetwork_Info, L"LoadNetworkInfo() completed.", hr );
  1362. if ( hIPAddress != NULL )
  1363. {
  1364. CloseClusterResource( hIPAddress );
  1365. } // if:
  1366. HRETURN( hr );
  1367. } //*** CClusCfgClusterInfo::HrLoadNetworkInfo
  1368. //////////////////////////////////////////////////////////////////////////////
  1369. //++
  1370. //
  1371. // CClusCfgClusterInfo::HrGetIPAddressInfo
  1372. //
  1373. // Description:
  1374. //
  1375. //
  1376. // Arguments:
  1377. //
  1378. //
  1379. // Return Value:
  1380. //
  1381. //
  1382. // Remarks:
  1383. // None.
  1384. //
  1385. //--
  1386. //////////////////////////////////////////////////////////////////////////////
  1387. HRESULT
  1388. CClusCfgClusterInfo::HrGetIPAddressInfo(
  1389. HCLUSTER hClusterIn,
  1390. HRESOURCE hResIn
  1391. )
  1392. {
  1393. TraceFunc( "" );
  1394. Assert( hClusterIn != NULL );
  1395. Assert( hResIn != NULL );
  1396. HRESULT hr = S_FALSE;
  1397. DWORD sc;
  1398. HRESENUM hEnum = NULL;
  1399. DWORD idx;
  1400. WCHAR * psz = NULL;
  1401. DWORD cchpsz = 33;
  1402. DWORD dwType;
  1403. HRESOURCE hRes = NULL;
  1404. hEnum = ClusterResourceOpenEnum( hResIn, CLUSTER_RESOURCE_ENUM_DEPENDS );
  1405. if ( hEnum == NULL )
  1406. {
  1407. sc = TW32( GetLastError() );
  1408. hr = HRESULT_FROM_WIN32( sc );
  1409. goto Cleanup;
  1410. } // if:
  1411. psz = new WCHAR [ cchpsz ];
  1412. if ( psz == NULL )
  1413. {
  1414. goto OutOfMemory;
  1415. } // if:
  1416. for ( idx = 0; ; )
  1417. {
  1418. sc = TW32( ClusterResourceEnum( hEnum, idx, &dwType, psz, &cchpsz ) );
  1419. if ( sc == ERROR_NO_MORE_ITEMS )
  1420. {
  1421. break;
  1422. } // if:
  1423. if ( sc == ERROR_MORE_DATA )
  1424. {
  1425. delete [] psz;
  1426. psz = NULL;
  1427. cchpsz++;
  1428. psz = new WCHAR [ cchpsz ];
  1429. if ( psz == NULL )
  1430. {
  1431. goto OutOfMemory;
  1432. } // if:
  1433. continue;
  1434. } // if:
  1435. if ( sc == ERROR_SUCCESS )
  1436. {
  1437. hRes = OpenClusterResource( hClusterIn, psz );
  1438. if ( hRes == NULL )
  1439. {
  1440. sc = TW32( GetLastError() );
  1441. hr = HRESULT_FROM_WIN32( sc );
  1442. goto Cleanup;
  1443. } // if:
  1444. hr = STHR( HrIsResourceOfType( hRes, L"IP Address" ) );
  1445. if ( FAILED( hr ) )
  1446. {
  1447. goto Cleanup;
  1448. } // if:
  1449. if ( hr == S_OK )
  1450. {
  1451. hr = THR( HrGetIPAddressInfo( hRes ) ); // not recursive!
  1452. break;
  1453. } // if:
  1454. CloseClusterResource( hRes );
  1455. hRes = NULL;
  1456. idx++;
  1457. continue;
  1458. } // if:
  1459. hr = THR( HRESULT_FROM_WIN32( sc ) ); // must be an error!
  1460. goto Cleanup;
  1461. } // for:
  1462. goto Cleanup;
  1463. OutOfMemory:
  1464. hr = THR( E_OUTOFMEMORY );
  1465. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrGetIPAddressInfo, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
  1466. Cleanup:
  1467. LOG_STATUS_REPORT_MINOR( TASKID_Minor_Server_Get_ClusterIPAddress_Info_2, L"GetIPAddressInfo() completed.", hr );
  1468. delete [] psz;
  1469. if ( hRes != NULL )
  1470. {
  1471. CloseClusterResource( hRes );
  1472. } // if:
  1473. if ( hEnum != NULL )
  1474. {
  1475. ClusterResourceCloseEnum( hEnum );
  1476. } // if:
  1477. HRETURN( hr );
  1478. } //*** CClusCfgClusterInfo::HrGetIPAddressInfo
  1479. //////////////////////////////////////////////////////////////////////////////
  1480. //++
  1481. //
  1482. // CClusCfgClusterInfo::HrGetIPAddressInfo
  1483. //
  1484. // Description:
  1485. //
  1486. //
  1487. // Arguments:
  1488. //
  1489. //
  1490. // Return Value:
  1491. //
  1492. //
  1493. // Remarks:
  1494. // None.
  1495. //
  1496. //--
  1497. //////////////////////////////////////////////////////////////////////////////
  1498. HRESULT
  1499. CClusCfgClusterInfo::HrGetIPAddressInfo(
  1500. HRESOURCE hResIn
  1501. )
  1502. {
  1503. TraceFunc( "" );
  1504. Assert( hResIn != NULL );
  1505. HRESULT hr = S_OK;
  1506. DWORD sc;
  1507. ULONG ulNetwork;
  1508. WCHAR * psz = NULL;
  1509. BSTR bstrNetworkName = NULL;
  1510. hr = THR( ::HrGetIPAddressInfo( hResIn, &m_ulIPDottedQuad, &m_ulSubnetDottedQuad, &bstrNetworkName ) );
  1511. if ( FAILED( hr ) )
  1512. {
  1513. LOG_STATUS_REPORT_MINOR( TASKID_Minor_Server_Get_IPAddressResource_Info, L"Could not get the IP address info.", hr );
  1514. goto Cleanup;
  1515. } // if:
  1516. sc = TW32( ClRtlTcpipAddressToString( m_ulIPDottedQuad, &psz ) ); // KB: Allocates to psz using LocalAlloc().
  1517. if ( sc != ERROR_SUCCESS )
  1518. {
  1519. hr = HRESULT_FROM_WIN32( sc );
  1520. LOG_STATUS_REPORT_MINOR( TASKID_Minor_Server_Convert_ClusterIPAddress_To_String, L"Could not convert the Cluster IP address to a string.", hr );
  1521. goto Cleanup;
  1522. } // if:
  1523. m_bstrBindingString = TraceSysAllocString( psz );
  1524. if ( m_bstrBindingString == NULL )
  1525. {
  1526. hr = THR( E_OUTOFMEMORY );
  1527. goto Cleanup;
  1528. } // if:
  1529. LocalFree( psz );
  1530. psz = NULL;
  1531. LOG_STATUS_REPORT_STRING( L"Cluster binding string is '%1!ws!'.", m_bstrBindingString, hr );
  1532. ulNetwork = m_ulIPDottedQuad & m_ulSubnetDottedQuad;
  1533. sc = TW32( ClRtlTcpipAddressToString( ulNetwork, &psz ) ); // KB: Allocates to psz using LocalAlloc().
  1534. if ( sc != ERROR_SUCCESS )
  1535. {
  1536. hr = HRESULT_FROM_WIN32( sc );
  1537. LOG_STATUS_REPORT_MINOR( TASKID_Minor_Server_Convert_Network_To_String, L"Could not convert the network address to a string.", hr );
  1538. goto Cleanup;
  1539. } // if:
  1540. hr = THR( HrFindNetworkInfo( bstrNetworkName, psz ) );
  1541. if ( FAILED( hr ) )
  1542. {
  1543. LOG_STATUS_REPORT_STRING_MINOR2( TASKID_Minor_Server_Find_Network, L"Could not find network %1!ws! with address %2!ws!.", bstrNetworkName, psz, hr );
  1544. goto Cleanup;
  1545. } // if:
  1546. Cleanup:
  1547. LOG_STATUS_REPORT_MINOR( TASKID_Minor_Server_Get_ClusterIPAddress_Info, L"GetIPAddressInfo() completed.", hr );
  1548. LocalFree( psz ); // KB: Don't use TraceFree() here! PREFAST may complain but their complaint is bogus.
  1549. TraceSysFreeString( bstrNetworkName );
  1550. HRETURN( hr );
  1551. } //*** CClusCfgClusterInfo::HrGetIPAddressInfo
  1552. //////////////////////////////////////////////////////////////////////////////
  1553. //++
  1554. //
  1555. // CClusCfgClusterInfo::HrFindNetworkInfo
  1556. //
  1557. // Description:
  1558. //
  1559. //
  1560. // Arguments:
  1561. //
  1562. //
  1563. // Return Value:
  1564. //
  1565. //
  1566. // Remarks:
  1567. // None.
  1568. //
  1569. //--
  1570. //////////////////////////////////////////////////////////////////////////////
  1571. HRESULT
  1572. CClusCfgClusterInfo::HrFindNetworkInfo(
  1573. const WCHAR * pszNetworkNameIn,
  1574. const WCHAR * pszNetworkIn
  1575. )
  1576. {
  1577. TraceFunc( "" );
  1578. Assert( pszNetworkNameIn != NULL );
  1579. Assert( pszNetworkIn != NULL );
  1580. HRESULT hr;
  1581. IUnknown * punk = NULL;
  1582. IEnumClusCfgNetworks * pieccn = NULL;
  1583. ULONG cFetched;
  1584. IClusCfgNetworkInfo * piccni = NULL;
  1585. BSTR bstrNetworkName = NULL;
  1586. BSTR bstrNetwork = NULL;
  1587. hr = THR( HrCreateNetworksEnum( m_picccCallback, m_lcid, m_pIWbemServices, &punk ) );
  1588. if ( FAILED( hr ) )
  1589. {
  1590. goto Cleanup;
  1591. } // if:
  1592. hr = THR( punk->TypeSafeQI( IEnumClusCfgNetworks, &pieccn ) );
  1593. if ( FAILED( hr ) )
  1594. {
  1595. goto Cleanup;
  1596. } // if:
  1597. for ( ; ; )
  1598. {
  1599. hr = pieccn->Next( 1, &piccni, &cFetched );
  1600. if ( ( hr == S_OK ) && ( cFetched == 1 ) )
  1601. {
  1602. hr = THR( piccni->GetName( &bstrNetworkName ) );
  1603. if ( FAILED( hr ) )
  1604. {
  1605. goto Cleanup;
  1606. } // if:
  1607. TraceMemoryAddBSTR( bstrNetworkName );
  1608. hr = THR( piccni->GetUID( &bstrNetwork ) );
  1609. if ( FAILED( hr ) )
  1610. {
  1611. goto Cleanup;
  1612. } // if:
  1613. TraceMemoryAddBSTR( bstrNetwork );
  1614. if ( ( wcscmp( pszNetworkNameIn, bstrNetworkName ) == 0 ) && ( ClRtlStrICmp( pszNetworkIn, bstrNetwork ) == 0 ) )
  1615. {
  1616. if ( m_piccniNetwork != NULL )
  1617. {
  1618. m_piccniNetwork->Release();
  1619. m_piccniNetwork = NULL;
  1620. } // if:
  1621. m_piccniNetwork = piccni;
  1622. m_piccniNetwork->AddRef();
  1623. break;
  1624. } // if:
  1625. piccni->Release();
  1626. piccni = NULL;
  1627. TraceSysFreeString( bstrNetworkName );
  1628. bstrNetworkName = NULL;
  1629. TraceSysFreeString( bstrNetwork );
  1630. bstrNetwork = NULL;
  1631. } // if:
  1632. else if ( ( hr == S_FALSE ) && ( cFetched == 0 ) )
  1633. {
  1634. hr = S_OK;
  1635. break;
  1636. } // else if:
  1637. else
  1638. {
  1639. goto Cleanup;
  1640. } // else:
  1641. } // for:
  1642. //
  1643. // If we didn't find the cluster network in the WMI list of networks then we have a problem.
  1644. //
  1645. Assert( m_piccniNetwork != NULL );
  1646. if ( m_piccniNetwork == NULL )
  1647. {
  1648. hr = THR( ERROR_NETWORK_NOT_AVAILABLE );
  1649. STATUS_REPORT_STRING_REF(
  1650. TASKID_Major_Find_Devices
  1651. , TASKID_Minor_Cluster_Network_Not_Found
  1652. , IDS_ERROR_CLUSTER_NETWORK_NOT_FOUND
  1653. , pszNetworkIn
  1654. , IDS_ERROR_CLUSTER_NETWORK_NOT_FOUND_REF
  1655. , hr
  1656. );
  1657. } // if:
  1658. Cleanup:
  1659. if ( piccni != NULL )
  1660. {
  1661. piccni->Release();
  1662. } // if:
  1663. if ( pieccn != NULL )
  1664. {
  1665. pieccn->Release();
  1666. } // if:
  1667. if ( punk != NULL )
  1668. {
  1669. punk->Release();
  1670. } // if:
  1671. TraceSysFreeString( bstrNetworkName );
  1672. TraceSysFreeString( bstrNetwork );
  1673. HRETURN( hr );
  1674. } //*** CClusCfgClusterInfo::HrFindNetworkInfo
  1675. //////////////////////////////////////////////////////////////////////////////
  1676. //++
  1677. //
  1678. // CClusCfgClusterInfo::HrLoadCredentials
  1679. //
  1680. // Description:
  1681. //
  1682. //
  1683. // Arguments:
  1684. // None.
  1685. //
  1686. // Return Value:
  1687. // S_OK - Operation completed successfully.
  1688. // S_FALSE - Nothing was done (cluster service doesn't exist).
  1689. // Other HRESULTs.
  1690. //
  1691. //--
  1692. //////////////////////////////////////////////////////////////////////////////
  1693. HRESULT
  1694. CClusCfgClusterInfo::HrLoadCredentials( void )
  1695. {
  1696. TraceFunc( "" );
  1697. HRESULT hr = S_OK;
  1698. SC_HANDLE schSCM = NULL;
  1699. SC_HANDLE schClusSvc = NULL;
  1700. DWORD sc;
  1701. DWORD cbRequired;
  1702. QUERY_SERVICE_CONFIG * pqsc = NULL;
  1703. DWORD cbqsc = 128;
  1704. IClusCfgCredentials * piccc = NULL;
  1705. IClusCfgSetCredentials * piccsc = NULL;
  1706. schSCM = OpenSCManager( NULL, NULL, GENERIC_READ );
  1707. if ( schSCM == NULL )
  1708. {
  1709. sc = TW32( GetLastError() );
  1710. goto Win32Error;
  1711. } // if:
  1712. schClusSvc = OpenService( schSCM, L"ClusSvc", GENERIC_READ );
  1713. if ( schClusSvc == NULL )
  1714. {
  1715. sc = GetLastError();
  1716. if ( sc == ERROR_SERVICE_DOES_NOT_EXIST )
  1717. {
  1718. hr = S_FALSE;
  1719. LogMsg( "[SRV] CClusCfgClusterInfo::HrLoadCredentials() - The cluster service does not exist." );
  1720. goto Cleanup;
  1721. }
  1722. TW32( sc );
  1723. goto Win32Error;
  1724. } // if:
  1725. for ( ; ; )
  1726. {
  1727. pqsc = (QUERY_SERVICE_CONFIG *) TraceAlloc( 0, cbqsc );
  1728. if ( pqsc == NULL )
  1729. {
  1730. hr = THR( E_OUTOFMEMORY );
  1731. STATUS_REPORT_REF( TASKID_Major_Find_Devices, TASKID_Minor_HrLoadCredentials, IDS_ERROR_OUTOFMEMORY, IDS_ERROR_OUTOFMEMORY_REF, hr );
  1732. goto Cleanup;
  1733. } // if:
  1734. if ( !QueryServiceConfig( schClusSvc, pqsc, cbqsc, &cbRequired ) )
  1735. {
  1736. sc = GetLastError();
  1737. if ( sc == ERROR_INSUFFICIENT_BUFFER )
  1738. {
  1739. TraceFree( pqsc );
  1740. pqsc = NULL;
  1741. cbqsc = cbRequired;
  1742. continue;
  1743. } // if:
  1744. else
  1745. {
  1746. TW32( sc );
  1747. goto Win32Error;
  1748. } // else:
  1749. } // if:
  1750. else
  1751. {
  1752. break;
  1753. } // else:
  1754. } // for:
  1755. Assert( m_punkServiceAccountCredentials == NULL );
  1756. hr = THR( GetClusterServiceAccountCredentials( &piccc ) );
  1757. if ( FAILED( hr ) )
  1758. {
  1759. goto Cleanup;
  1760. } // if:
  1761. hr = THR( piccc->TypeSafeQI( IClusCfgSetCredentials, &piccsc ) );
  1762. if ( FAILED( hr ) )
  1763. {
  1764. goto Cleanup;
  1765. } // if:
  1766. hr = THR( piccsc->SetDomainCredentials( pqsc->lpServiceStartName ) );
  1767. goto Cleanup;
  1768. Win32Error:
  1769. hr = HRESULT_FROM_WIN32( sc );
  1770. Cleanup:
  1771. if ( schClusSvc != NULL )
  1772. {
  1773. CloseServiceHandle( schClusSvc );
  1774. } // if:
  1775. if ( schSCM != NULL )
  1776. {
  1777. CloseServiceHandle( schSCM );
  1778. } // if:
  1779. if ( pqsc != NULL )
  1780. {
  1781. TraceFree( pqsc );
  1782. } // if:
  1783. if ( piccc != NULL )
  1784. {
  1785. piccc->Release();
  1786. } // if:
  1787. if ( piccsc != NULL )
  1788. {
  1789. piccsc->Release();
  1790. } // if:
  1791. HRETURN( hr );
  1792. } //*** CClusCfgClusterInfo::HrLoadCredentials