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.

8100 lines
256 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // PostCfgManager.cpp
  7. //
  8. // Description:
  9. // CPostCfgManager implementation.
  10. //
  11. // Maintained By:
  12. // Galen Barbee (GalenB) 09-JUN-2000
  13. // Ozan Ozhan (OzanO) 10-JUN-2001
  14. //
  15. //////////////////////////////////////////////////////////////////////////////
  16. #include "Pch.h"
  17. #include "Guids.h"
  18. #include <clusudef.h>
  19. #include "GroupHandle.h"
  20. #include "ResourceEntry.h"
  21. #include "IPostCfgManager.h"
  22. #include "IPrivatePostCfgResource.h"
  23. #include "PostCfgMgr.h"
  24. #include "CreateServices.h"
  25. #include "PostCreateServices.h"
  26. #include "PreCreateServices.h"
  27. #include "ResTypeServices.h"
  28. #include "..\Wizard\Resource.h"
  29. #include "ClusCfgPrivate.h"
  30. #include <ResApi.h>
  31. #include <ClusterUtils.h>
  32. DEFINE_THISCLASS("CPostCfgManager")
  33. #define RESOURCE_INCREMENT 25
  34. //
  35. // Failure code.
  36. //
  37. #define SSR_LOG_ERR( _major, _minor, _hr, _msg ) \
  38. { \
  39. THR( SendStatusReport( m_bstrNodeName, _major, _minor, 0, 0, 0, _hr, _msg, NULL, NULL ) ); \
  40. }
  41. #define SSR_LOG1( _major, _minor, _hr, _fmt, _bstr, _arg1 ) \
  42. { \
  43. HRESULT hrTemp; \
  44. THR( HrFormatStringIntoBSTR( _fmt, &_bstr, _arg1 ) ); \
  45. hrTemp = THR( SendStatusReport( m_bstrNodeName, _major, _minor, 0, 1, 1, _hr, _bstr, NULL, NULL ) ); \
  46. if ( FAILED( hrTemp ) )\
  47. { \
  48. _hr = hrTemp; \
  49. } \
  50. }
  51. #define SSR_LOG2( _major, _minor, _hr, _fmt, _bstr, _arg1, _arg2 ) \
  52. { \
  53. HRESULT hrTemp; \
  54. THR( HrFormatStringIntoBSTR( _fmt, &_bstr, _arg1, _arg2 ) ); \
  55. hrTemp = THR( SendStatusReport( m_bstrNodeName, _major, _minor, 0, 1, 1, _hr, _bstr, NULL, NULL ) ); \
  56. if ( FAILED( hrTemp ) )\
  57. { \
  58. _hr = hrTemp; \
  59. } \
  60. }
  61. //
  62. // Structure that holds the mapping for well known resource types.
  63. //
  64. struct SResTypeGUIDPtrAndName
  65. {
  66. const GUID * m_pcguidTypeGUID;
  67. const WCHAR * m_pszTypeName;
  68. };
  69. // Mapping of well known resource type GUIDs to the type names.
  70. const SResTypeGUIDPtrAndName gc_rgWellKnownResTypeMap[] =
  71. {
  72. {
  73. &RESTYPE_PhysicalDisk,
  74. CLUS_RESTYPE_NAME_PHYS_DISK
  75. },
  76. {
  77. &RESTYPE_IPAddress,
  78. CLUS_RESTYPE_NAME_IPADDR
  79. },
  80. {
  81. &RESTYPE_NetworkName,
  82. CLUS_RESTYPE_NAME_NETNAME
  83. },
  84. {
  85. &RESTYPE_LocalQuorum,
  86. CLUS_RESTYPE_NAME_LKQUORUM
  87. }
  88. };
  89. // Size of the above array.
  90. const int gc_cWellKnownResTypeMapSize = ARRAYSIZE( gc_rgWellKnownResTypeMap );
  91. // ************************************************************************
  92. //
  93. // Constructor / Destructor
  94. //
  95. // ************************************************************************
  96. //////////////////////////////////////////////////////////////////////////////
  97. //
  98. // HRESULT
  99. // CPostCfgManager::S_HrCreateInstance(
  100. // IUnknown ** ppunkOut
  101. // )
  102. //
  103. //////////////////////////////////////////////////////////////////////////////
  104. HRESULT
  105. CPostCfgManager::S_HrCreateInstance(
  106. IUnknown ** ppunkOut
  107. )
  108. {
  109. TraceFunc( "" );
  110. HRESULT hr = S_OK;
  111. CPostCfgManager * ppcm = NULL;
  112. Assert( ppunkOut != NULL );
  113. if ( ppunkOut == NULL )
  114. {
  115. hr = THR( E_POINTER );
  116. goto Cleanup;
  117. }
  118. ppcm = new CPostCfgManager;
  119. if ( ppcm == NULL )
  120. {
  121. hr = THR( E_OUTOFMEMORY );
  122. goto Cleanup;
  123. }
  124. hr = THR( ppcm->HrInit() );
  125. if ( FAILED( hr ) )
  126. {
  127. goto Cleanup;
  128. }
  129. hr = THR( ppcm->TypeSafeQI( IUnknown, ppunkOut ) );
  130. if ( FAILED( hr ) )
  131. {
  132. goto Cleanup;
  133. }
  134. Cleanup:
  135. if ( ppcm != NULL )
  136. {
  137. ppcm->Release();
  138. }
  139. HRETURN( hr );
  140. } //*** CPostCfgManager::S_HrCreateInstance
  141. //////////////////////////////////////////////////////////////////////////////
  142. //
  143. // CPostCfgManager::CPostCfgManager
  144. //
  145. //////////////////////////////////////////////////////////////////////////////
  146. CPostCfgManager::CPostCfgManager( void )
  147. : m_cRef( 1 )
  148. {
  149. TraceFunc( "" );
  150. InterlockedIncrement( &g_cObjects );
  151. TraceFuncExit();
  152. } //*** CPostCfgManager::CPostCfgManager
  153. //////////////////////////////////////////////////////////////////////////////
  154. //++
  155. //
  156. // CPostCfgManager::HrInit
  157. //
  158. // Description:
  159. // Initialize the object.
  160. //
  161. // Arguments:
  162. // None.
  163. //
  164. // Return Values:
  165. // S_OK - Success.
  166. // Other HRESULTs.
  167. //
  168. //--
  169. //////////////////////////////////////////////////////////////////////////////
  170. HRESULT
  171. CPostCfgManager::HrInit( void )
  172. {
  173. TraceFunc( "" );
  174. ULONG idxMapEntry;
  175. HRESULT hr = S_OK;
  176. // IUnknown stuff
  177. Assert( m_cRef == 1 );
  178. Assert( m_pcccb == NULL );
  179. Assert( m_lcid == 0 );
  180. // IPostCfgManager
  181. Assert( m_peccmr == NULL );
  182. Assert( m_pccci == NULL );
  183. Assert( m_cAllocedResources == 0 );
  184. Assert( m_cResources == 0 );
  185. Assert( m_rgpResources == NULL );
  186. Assert( m_idxIPAddress == 0 );
  187. Assert( m_idxClusterName == 0 );
  188. Assert( m_idxQuorumResource == 0 );
  189. Assert( m_idxLastStorage == 0 );
  190. Assert( m_hCluster == NULL );
  191. Assert( m_pgnResTypeGUIDNameMap == NULL );
  192. Assert( m_idxNextMapEntry == 0 );
  193. Assert( m_cMapSize == 0 );
  194. Assert( m_ecmCommitChangesMode == cmUNKNOWN );
  195. m_cNetName = 1;
  196. m_cIPAddress = 1;
  197. // Set the boolean flag, m_fIsQuorumChanged to FALSE.
  198. m_fIsQuorumChanged = FALSE;
  199. // Default allocation for mappings
  200. m_cMapSize = 20;
  201. m_pgnResTypeGUIDNameMap = new SResTypeGUIDAndName[ m_cMapSize ];
  202. if ( m_pgnResTypeGUIDNameMap == NULL )
  203. {
  204. hr = THR( E_OUTOFMEMORY );
  205. SSR_LOG_ERR(
  206. TASKID_Major_Client_And_Server_Log
  207. , TASKID_Minor_Init_OutOfMemory
  208. , hr
  209. , L"Out of memory"
  210. );
  211. STATUS_REPORT_REF_POSTCFG(
  212. TASKID_Major_Configure_Resources
  213. , TASKID_Minor_Init_OutOfMemory
  214. , IDS_TASKID_MINOR_ERROR_OUT_OF_MEMORY
  215. , IDS_REF_MINOR_ERROR_OUT_OF_MEMORY
  216. , hr
  217. );
  218. goto Cleanup;
  219. }
  220. // Prefill the resource type GUID to name map with well known entries.
  221. for ( idxMapEntry = 0; idxMapEntry < gc_cWellKnownResTypeMapSize; ++idxMapEntry )
  222. {
  223. hr = THR(
  224. HrMapResTypeGUIDToName(
  225. *gc_rgWellKnownResTypeMap[ idxMapEntry ].m_pcguidTypeGUID
  226. , gc_rgWellKnownResTypeMap [ idxMapEntry ].m_pszTypeName
  227. )
  228. );
  229. if ( FAILED( hr ) )
  230. {
  231. SSR_LOG_ERR(
  232. TASKID_Major_Client_And_Server_Log
  233. , TASKID_Minor_Init_MapResTypeGuidToName
  234. , hr
  235. , L"Mapping resource type GUID to name failed."
  236. );
  237. STATUS_REPORT_MINOR_REF_POSTCFG1(
  238. TASKID_Major_Configure_Resources
  239. , IDS_TASKID_MINOR_INIT_MAPRESTYPEGUIDTONAME
  240. , IDS_REF_MINOR_INIT_MAPRESTYPEGUIDTONAME
  241. , hr
  242. , gc_rgWellKnownResTypeMap [ idxMapEntry ].m_pszTypeName
  243. );
  244. break;
  245. } // if: there was an error creating a mapping
  246. } // for
  247. hr = THR( HrGetComputerName(
  248. ComputerNameDnsHostname
  249. , &m_bstrNodeName
  250. , TRUE // fBestEffortIn
  251. ) );
  252. if ( FAILED( hr ) )
  253. {
  254. goto Cleanup;
  255. }
  256. Cleanup:
  257. HRETURN( hr );
  258. } //*** CPostCfgManager::HrInit
  259. //////////////////////////////////////////////////////////////////////////////
  260. //
  261. // CPostCfgManager::~CPostCfgManager
  262. //
  263. //////////////////////////////////////////////////////////////////////////////
  264. CPostCfgManager::~CPostCfgManager( void )
  265. {
  266. TraceFunc( "" );
  267. ULONG idxMapEntry;
  268. if ( m_peccmr != NULL )
  269. {
  270. m_peccmr->Release();
  271. }
  272. if ( m_pcccb != NULL )
  273. {
  274. m_pcccb->Release();
  275. }
  276. if ( m_pccci != NULL )
  277. {
  278. m_pccci->Release();
  279. }
  280. if ( m_rgpResources != NULL )
  281. {
  282. while ( m_cAllocedResources != 0 )
  283. {
  284. m_cAllocedResources --;
  285. delete m_rgpResources[ m_cAllocedResources ];
  286. }
  287. TraceFree( m_rgpResources );
  288. }
  289. if ( m_hCluster != NULL )
  290. {
  291. CloseCluster( m_hCluster );
  292. }
  293. // Free the resource type GUID to name map entries
  294. for ( idxMapEntry = 0; idxMapEntry < m_idxNextMapEntry; ++idxMapEntry )
  295. {
  296. delete m_pgnResTypeGUIDNameMap[ idxMapEntry ].m_pszTypeName;
  297. } // for: iterate through the map, freeing each entry
  298. // Free the map itself.
  299. delete [] m_pgnResTypeGUIDNameMap;
  300. TraceSysFreeString( m_bstrNodeName );
  301. InterlockedDecrement( &g_cObjects );
  302. TraceFuncExit();
  303. } //*** CPostCfgManager::~CPostCfgManager
  304. // ************************************************************************
  305. //
  306. // IUnknown
  307. //
  308. // ************************************************************************
  309. //////////////////////////////////////////////////////////////////////////////
  310. //++
  311. //
  312. // CPostCfgManager::QueryInterface
  313. //
  314. // Description:
  315. // Query this object for the passed in interface.
  316. //
  317. // Arguments:
  318. // riidIn
  319. // Id of interface requested.
  320. //
  321. // ppvOut
  322. // Pointer to the requested interface.
  323. //
  324. // Return Value:
  325. // S_OK
  326. // If the interface is available on this object.
  327. //
  328. // E_NOINTERFACE
  329. // If the interface is not available.
  330. //
  331. // E_POINTER
  332. // ppvOut was NULL.
  333. //
  334. // Remarks:
  335. // None.
  336. //
  337. //--
  338. //////////////////////////////////////////////////////////////////////////////
  339. STDMETHODIMP
  340. CPostCfgManager::QueryInterface(
  341. REFIID riidIn
  342. , LPVOID * ppvOut
  343. )
  344. {
  345. TraceQIFunc( riidIn, ppvOut );
  346. HRESULT hr = S_OK;
  347. //
  348. // Validate arguments.
  349. //
  350. Assert( ppvOut != NULL );
  351. if ( ppvOut == NULL )
  352. {
  353. hr = THR( E_POINTER );
  354. goto Cleanup;
  355. }
  356. //
  357. // Handle known interfaces.
  358. //
  359. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  360. {
  361. *ppvOut = static_cast< IPostCfgManager * >( this );
  362. } // if: IUnknown
  363. else if ( IsEqualIID( riidIn, IID_IPostCfgManager ) )
  364. {
  365. *ppvOut = TraceInterface( __THISCLASS__, IPostCfgManager, this, 0 );
  366. } // else if: IPostCfgManager
  367. else if ( IsEqualIID( riidIn, IID_IClusCfgInitialize ) )
  368. {
  369. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 );
  370. } // else if: IClusCfgInitialize
  371. else if ( IsEqualIID( riidIn, IID_IClusCfgCallback ) )
  372. {
  373. *ppvOut = TraceInterface( __THISCLASS__, IClusCfgCallback, this, 0 );
  374. } // else if: IClusCfgInitialize
  375. else
  376. {
  377. *ppvOut = NULL;
  378. hr = E_NOINTERFACE;
  379. }
  380. //
  381. // Add a reference to the interface if successful.
  382. //
  383. if ( SUCCEEDED( hr ) )
  384. {
  385. ((IUnknown *) *ppvOut)->AddRef();
  386. } // if: success
  387. Cleanup:
  388. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  389. } //*** CPostCfgManager::QueryInterface
  390. //////////////////////////////////////////////////////////////////////////////
  391. //
  392. // STDMETHODIMP_(ULONG)
  393. // CPostCfgManager::AddRef
  394. //
  395. //////////////////////////////////////////////////////////////////////////////
  396. STDMETHODIMP_( ULONG )
  397. CPostCfgManager::AddRef( void )
  398. {
  399. TraceFunc( "[IUnknown]" );
  400. InterlockedIncrement( &m_cRef );
  401. CRETURN( m_cRef );
  402. } //*** CPostCfgManager::AddRef
  403. //////////////////////////////////////////////////////////////////////////////
  404. //
  405. // STDMETHODIMP_(ULONG)
  406. // CPostCfgManager::Release
  407. //
  408. //////////////////////////////////////////////////////////////////////////////
  409. STDMETHODIMP_( ULONG )
  410. CPostCfgManager::Release( void )
  411. {
  412. TraceFunc( "[IUnknown]" );
  413. LONG cRef;
  414. cRef = InterlockedDecrement( &m_cRef );
  415. if ( cRef == 0 )
  416. {
  417. TraceDo( delete this );
  418. }
  419. CRETURN( cRef );
  420. } //*** CPostCfgManager::Release
  421. //****************************************************************************
  422. //
  423. // IClusCfgInitialize
  424. //
  425. //****************************************************************************
  426. /////////////////////////////////////////////////////////////////////////////
  427. //++
  428. //
  429. // CPostCfgManager::Initialize
  430. //
  431. // Description:
  432. // Initialize this component.
  433. //
  434. // Arguments:
  435. // punkCallbackIn
  436. // Pointer to the IUnknown interface of a component that implements
  437. // the IClusCfgCallback interface.
  438. //
  439. // lcidIn
  440. // Locale id for this component.
  441. //
  442. // Return Value:
  443. // S_OK
  444. // If the call succeeded
  445. //
  446. // Other HRESULTs
  447. // If the call failed.
  448. //
  449. //--
  450. //////////////////////////////////////////////////////////////////////////////
  451. STDMETHODIMP
  452. CPostCfgManager::Initialize(
  453. IUnknown * punkCallbackIn
  454. , LCID lcidIn
  455. )
  456. {
  457. TraceFunc( "[IClusCfgInitialize]" );
  458. HRESULT hr = S_OK;
  459. IClusCfgCallback * pcccb = NULL;
  460. if ( punkCallbackIn != NULL )
  461. {
  462. hr = THR( punkCallbackIn->TypeSafeQI( IClusCfgCallback, &pcccb ) );
  463. if ( FAILED( hr ) )
  464. {
  465. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log, TASKID_Minor_Initialize_QI, hr, L"Failed QI for IClusCfgCallback." );
  466. STATUS_REPORT_REF_POSTCFG(
  467. TASKID_Major_Configure_Resources
  468. , TASKID_Minor_Initialize_QI
  469. , IDS_TASKID_MINOR_ERROR_INIT_POSTCFGMGR
  470. , IDS_REF_MINOR_ERROR_INIT_POSTCFGMGR
  471. , hr
  472. );
  473. goto Cleanup;
  474. }
  475. }
  476. m_lcid = lcidIn;
  477. // Release any previous callback.
  478. if ( m_pcccb != NULL )
  479. {
  480. m_pcccb->Release();
  481. }
  482. // Give ownership away
  483. m_pcccb = pcccb;
  484. pcccb = NULL;
  485. #if defined(DEBUG)
  486. if ( m_pcccb != NULL )
  487. {
  488. m_pcccb = TraceInterface( L"CPostCfgManager!IClusCfgCallback", IClusCfgCallback, m_pcccb, 1 );
  489. }
  490. #endif // DEBUG
  491. Cleanup:
  492. if ( pcccb != NULL )
  493. {
  494. pcccb->Release();
  495. }
  496. HRETURN( hr );
  497. } //*** CPostCfgManager::Initialize
  498. //****************************************************************************
  499. //
  500. // IPostCfgManager
  501. //
  502. //****************************************************************************
  503. //////////////////////////////////////////////////////////////////////////////
  504. //
  505. // STDMETHODIMP
  506. // CPostCfgManager::CommitChanges(
  507. // IEnumClusCfgManagedResources * peccmrIn,
  508. // IClusCfgClusterInfo * pccciIn
  509. // )
  510. //
  511. //////////////////////////////////////////////////////////////////////////////
  512. STDMETHODIMP
  513. CPostCfgManager::CommitChanges(
  514. IEnumClusCfgManagedResources * peccmrIn,
  515. IClusCfgClusterInfo * pccciIn
  516. )
  517. {
  518. TraceFunc( "[IPostCfgManager]" );
  519. HRESULT hr;
  520. DWORD dw;
  521. IClusCfgResTypeServicesInitialize * pccrtsiResTypeServicesInit = NULL;
  522. IClusCfgInitialize * pcci = NULL;
  523. // Validate parameters
  524. Assert( peccmrIn != NULL );
  525. Assert( pccciIn != NULL );
  526. //
  527. // Grab our interfaces.
  528. //
  529. if ( m_peccmr != NULL )
  530. {
  531. m_peccmr->Release();
  532. }
  533. hr = THR( peccmrIn->TypeSafeQI( IEnumClusCfgManagedResources, &m_peccmr ) );
  534. if ( FAILED( hr ) )
  535. {
  536. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log, TASKID_Minor_CommitChanges_QI_Resources, hr, L"Failed QI for IEnumClusCfgManagedResources." );
  537. STATUS_REPORT_REF_POSTCFG(
  538. TASKID_Major_Configure_Resources
  539. , TASKID_Minor_CommitChanges_QI_Resources
  540. , IDS_TASKID_MINOR_ERROR_COMMIT_CHANGES
  541. , IDS_REF_MINOR_ERROR_COMMIT_CHANGES
  542. , hr
  543. );
  544. goto Cleanup;
  545. }
  546. if ( m_pccci != NULL )
  547. {
  548. m_pccci->Release();
  549. }
  550. hr = THR( pccciIn->TypeSafeQI( IClusCfgClusterInfo, &m_pccci ) );
  551. if ( FAILED( hr ) )
  552. {
  553. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log, TASKID_Minor_CommitChanges_QI_ClusterInfo, hr, L"Failed QI for IClusCfgClusterInfo." );
  554. STATUS_REPORT_REF_POSTCFG(
  555. TASKID_Major_Configure_Resources
  556. , TASKID_Minor_CommitChanges_QI_ClusterInfo
  557. , IDS_TASKID_MINOR_ERROR_COMMIT_CHANGES
  558. , IDS_REF_MINOR_ERROR_COMMIT_CHANGES
  559. , hr
  560. );
  561. goto Cleanup;
  562. }
  563. //
  564. // Are we creating, adding nodes, or have we been evicted?
  565. //
  566. hr = STHR( pccciIn->GetCommitMode( &m_ecmCommitChangesMode ) );
  567. if ( FAILED( hr ) )
  568. {
  569. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log, TASKID_Minor_CommitChanges_GetCommitMode, hr, L"Failed to get commit mode" );
  570. STATUS_REPORT_REF_POSTCFG(
  571. TASKID_Major_Configure_Resources
  572. , TASKID_Minor_CommitChanges_GetCommitMode
  573. , IDS_TASKID_MINOR_ERROR_COMMIT_MODE
  574. , IDS_REF_MINOR_ERROR_COMMIT_MODE
  575. , hr
  576. );
  577. goto Cleanup;
  578. }
  579. //
  580. // Create an instance of the resource type services component
  581. //
  582. hr = THR(
  583. HrCoCreateInternalInstance(
  584. CLSID_ClusCfgResTypeServices
  585. , NULL
  586. , CLSCTX_INPROC_SERVER
  587. , __uuidof( pccrtsiResTypeServicesInit )
  588. , reinterpret_cast< void ** >( &pccrtsiResTypeServicesInit )
  589. )
  590. );
  591. if ( FAILED( hr ) )
  592. {
  593. SSR_LOG_ERR(
  594. TASKID_Major_Client_And_Server_Log
  595. , TASKID_Minor_CommitChanges_CoCreate_ResTypeService
  596. , hr
  597. , L"[PC-PostCfg] Error occurred trying to create the resource type services component"
  598. );
  599. STATUS_REPORT_REF_POSTCFG(
  600. TASKID_Major_Configure_Resources
  601. , TASKID_Minor_CommitChanges_CoCreate_ResTypeService
  602. , IDS_TASKID_MINOR_ERROR_CREATE_RESOURCE_SERVICE
  603. , IDS_REF_MINOR_ERROR_CREATE_RESOURCE_SERVICE
  604. , hr
  605. );
  606. goto Cleanup;
  607. } // if: we could not create the resource type services component
  608. hr = THR( pccrtsiResTypeServicesInit->TypeSafeQI( IClusCfgInitialize, &pcci ) );
  609. if ( FAILED( hr ) )
  610. {
  611. SSR_LOG_ERR(
  612. TASKID_Major_Client_And_Server_Log
  613. , TASKID_Minor_CPostCfgManager_CommitChanges_TypeSafeQI
  614. , hr
  615. , L"[PC-PostCfg] Error occurred trying to QI for IClusCfgInitialize."
  616. );
  617. STATUS_REPORT_REF_POSTCFG(
  618. TASKID_Major_Configure_Resources
  619. , TASKID_Minor_CPostCfgManager_CommitChanges_TypeSafeQI
  620. , IDS_TASKID_MINOR_ERROR_GET_ICLUSCFGINIT
  621. , IDS_REF_MINOR_ERROR_GET_ICLUSCFGINIT
  622. , hr
  623. );
  624. goto Cleanup;
  625. }
  626. hr = THR( pcci->Initialize( static_cast< IClusCfgCallback * >( this ) , m_lcid ) );
  627. if ( FAILED( hr ) )
  628. {
  629. SSR_LOG_ERR(
  630. TASKID_Major_Client_And_Server_Log
  631. , TASKID_Minor_CPostCfgManager_CommitChanges_Initialize
  632. , hr
  633. , L"[PC-PostCfg] Error occurred trying to call of Initialize function of IClusCfgInitialize."
  634. );
  635. STATUS_REPORT_REF_POSTCFG(
  636. TASKID_Major_Configure_Resources
  637. , TASKID_Minor_CPostCfgManager_CommitChanges_Initialize
  638. , IDS_TASKID_MINOR_ERROR_CALL_INITIALIZE
  639. , IDS_REF_MINOR_ERROR_CALL_INITIALIZE
  640. , hr
  641. );
  642. goto Cleanup;
  643. }
  644. // This interface is no longer needed.
  645. pcci->Release();
  646. pcci = NULL;
  647. // Initialize the resource type services component.
  648. hr = THR( pccrtsiResTypeServicesInit->SetParameters( m_pccci ) );
  649. if ( FAILED( hr ) )
  650. {
  651. SSR_LOG_ERR(
  652. TASKID_Major_Client_And_Server_Log
  653. , TASKID_Minor_CommitChanges_SetParameters
  654. , hr
  655. , L"[PC-PostCfg] Error occurred trying to initialize the resource type services component."
  656. );
  657. STATUS_REPORT_REF_POSTCFG(
  658. TASKID_Major_Configure_Resources
  659. , TASKID_Minor_CommitChanges_SetParameters
  660. , IDS_TASKID_MINOR_ERROR_INIT_RESOURCE_SERVICE
  661. , IDS_REF_MINOR_ERROR_INIT_RESOURCE_SERVICE
  662. , hr
  663. );
  664. goto Cleanup;
  665. } // if: we could not initialize the resource type services component
  666. if ( ( m_ecmCommitChangesMode == cmCREATE_CLUSTER ) || ( m_ecmCommitChangesMode == cmADD_NODE_TO_CLUSTER ) )
  667. {
  668. //
  669. // Make sure we have all we need to be successful!
  670. //
  671. if ( m_hCluster == NULL )
  672. {
  673. m_hCluster = OpenCluster( NULL );
  674. if ( m_hCluster == NULL )
  675. {
  676. dw = GetLastError();
  677. hr = HRESULT_FROM_WIN32( TW32( dw ) );
  678. SSR_LOG_ERR(
  679. TASKID_Major_Client_And_Server_Log
  680. , TASKID_Minor_CommitChanges_OpenCluster
  681. , hr
  682. , L"[PC-PostCfg] Failed to get cluster handle. Aborting."
  683. );
  684. STATUS_REPORT_REF_POSTCFG(
  685. TASKID_Major_Configure_Resources
  686. , TASKID_Minor_CommitChanges_OpenCluster
  687. , IDS_TASKID_MINOR_ERROR_CLUSTER_HANDLE
  688. , IDS_REF_MINOR_ERROR_CLUSTER_HANDLE
  689. , hr
  690. );
  691. goto Cleanup;
  692. }
  693. } // if: cluster not open yet
  694. //
  695. // Configure resource types.
  696. //
  697. hr = THR( HrConfigureResTypes( pccrtsiResTypeServicesInit ) );
  698. if ( FAILED( hr ) )
  699. {
  700. goto Cleanup;
  701. }
  702. //
  703. // Create the resource instances.
  704. //
  705. hr = THR( HrPreCreateResources() );
  706. if ( FAILED( hr ) )
  707. {
  708. goto Cleanup;
  709. }
  710. hr = THR( HrCreateGroups() );
  711. if ( FAILED( hr ) )
  712. {
  713. //
  714. // MUSTDO: gpease 28-SEP-2000
  715. // For Beta1 will we ignore errors in group creation
  716. // and abort the process.
  717. //
  718. hr = S_OK;
  719. goto Cleanup;
  720. }
  721. hr = THR( HrCreateResources() );
  722. if ( FAILED( hr ) )
  723. {
  724. goto Cleanup;
  725. }
  726. hr = THR( HrPostCreateResources() );
  727. if ( FAILED( hr ) )
  728. {
  729. goto Cleanup;
  730. }
  731. //
  732. // Notify any components registered on this computer, of a cluster
  733. // member set change ( form, join or evict ).
  734. //
  735. hr = THR( HrNotifyMemberSetChangeListeners() );
  736. if ( FAILED( hr ) )
  737. {
  738. goto Cleanup;
  739. }
  740. } // if: we are forming or joining
  741. else if ( m_ecmCommitChangesMode == cmCLEANUP_NODE_AFTER_EVICT )
  742. {
  743. //
  744. // Notify any components registered on this computer, of a cluster
  745. // member set change ( form, join or evict ).
  746. //
  747. hr = THR( HrNotifyMemberSetChangeListeners() );
  748. if ( FAILED( hr ) )
  749. {
  750. goto Cleanup;
  751. }
  752. //
  753. // Cleanup managed resources.
  754. //
  755. hr = THR( HrEvictCleanupResources() );
  756. if ( FAILED( hr ) )
  757. {
  758. goto Cleanup;
  759. }
  760. //
  761. // Configure resource types.
  762. //
  763. hr = THR( HrConfigureResTypes( pccrtsiResTypeServicesInit ) );
  764. if ( FAILED( hr ) )
  765. {
  766. goto Cleanup;
  767. }
  768. } // else if: we have just been evicted
  769. Cleanup:
  770. if ( pccrtsiResTypeServicesInit != NULL )
  771. {
  772. pccrtsiResTypeServicesInit->Release();
  773. } // if: we had created the resource type services component
  774. if ( pcci != NULL )
  775. {
  776. pcci->Release();
  777. } // if:
  778. HRETURN( hr );
  779. } //*** CPostCfgManager::CommitChanges
  780. //****************************************************************************
  781. //
  782. // IClusCfgCallback
  783. //
  784. //****************************************************************************
  785. STDMETHODIMP
  786. CPostCfgManager::SendStatusReport(
  787. LPCWSTR pcszNodeNameIn
  788. , CLSID clsidTaskMajorIn
  789. , CLSID clsidTaskMinorIn
  790. , ULONG ulMinIn
  791. , ULONG ulMaxIn
  792. , ULONG ulCurrentIn
  793. , HRESULT hrStatusIn
  794. , LPCWSTR pcszDescriptionIn
  795. , FILETIME * pftTimeIn
  796. , LPCWSTR pcszReferenceIn
  797. )
  798. {
  799. TraceFunc( "[IClusCfgCallback]" );
  800. HRESULT hr = S_OK;
  801. FILETIME ft;
  802. if ( pftTimeIn == NULL )
  803. {
  804. GetSystemTimeAsFileTime( &ft );
  805. pftTimeIn = &ft;
  806. } // if:
  807. if ( m_pcccb != NULL )
  808. {
  809. hr = STHR( m_pcccb->SendStatusReport(
  810. pcszNodeNameIn != NULL ? pcszNodeNameIn : m_bstrNodeName
  811. , clsidTaskMajorIn
  812. , clsidTaskMinorIn
  813. , ulMinIn
  814. , ulMaxIn
  815. , ulCurrentIn
  816. , hrStatusIn
  817. , pcszDescriptionIn
  818. , pftTimeIn
  819. , pcszReferenceIn
  820. ) );
  821. }
  822. HRETURN( hr );
  823. } //*** CPostCfgManager::SendStatusReport
  824. //****************************************************************************
  825. //
  826. // Private methods
  827. //
  828. //****************************************************************************
  829. //////////////////////////////////////////////////////////////////////////////
  830. //
  831. // HRESULT
  832. // CPostCfgManager::HrPreCreateResources( void )
  833. //
  834. //////////////////////////////////////////////////////////////////////////////
  835. HRESULT
  836. CPostCfgManager::HrPreCreateResources( void )
  837. {
  838. TraceFunc( "" );
  839. CResourceEntry * presentry;
  840. HRESULT hr = S_OK;
  841. BSTR bstrName = NULL;
  842. BSTR bstrNotification = NULL;
  843. BSTR bstrTemp = NULL;
  844. IClusCfgManagedResourceInfo * pccmri = NULL;
  845. IClusCfgManagedResourceCfg * pccmrc = NULL;
  846. IUnknown * punkServices = NULL;
  847. IPrivatePostCfgResource * ppcr = NULL;
  848. // Validate state
  849. Assert( m_peccmr != NULL );
  850. Assert( m_pccci != NULL );
  851. LogMsg( "[PC-PreCreate] Starting pre-create..." );
  852. hr = THR( HrPreInitializeExistingResources() );
  853. if ( FAILED( hr ) )
  854. {
  855. goto Cleanup;
  856. }
  857. //
  858. // Make sure the enumer is in the state we think it is.
  859. //
  860. hr = STHR( m_peccmr->Reset() );
  861. if ( FAILED( hr ) )
  862. {
  863. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log, TASKID_Minor_PreCreate_Reset, hr, L"Enumeration of managed resources failed to reset." );
  864. STATUS_REPORT_REF_POSTCFG(
  865. TASKID_Major_Configure_Resources
  866. , TASKID_Minor_PreCreate_Reset
  867. , IDS_TASKID_MINOR_ERROR_ENUM_MANAGEDRES
  868. , IDS_REF_MINOR_ERROR_ENUM_MANAGEDRES
  869. , hr
  870. );
  871. goto Cleanup;
  872. }
  873. hr = THR( CPreCreateServices::S_HrCreateInstance( &punkServices ) );
  874. if ( FAILED( hr ) )
  875. {
  876. SSR_LOG_ERR(
  877. TASKID_Major_Client_And_Server_Log
  878. , TASKID_Minor_PreCreate_CPreCreateServices
  879. , hr
  880. , L"[PC-PreCreate] Failed to create services object. Aborting."
  881. );
  882. STATUS_REPORT_REF_POSTCFG(
  883. TASKID_Major_Configure_Resources
  884. , TASKID_Minor_PreCreate_CPreCreateServices
  885. , IDS_TASKID_MINOR_ERROR_CREATE_SERVICE
  886. , IDS_REF_MINOR_ERROR_CREATE_SERVICE
  887. , hr
  888. );
  889. goto Cleanup;
  890. }
  891. hr = THR( punkServices->TypeSafeQI( IPrivatePostCfgResource, &ppcr ) );
  892. if ( FAILED( hr ) )
  893. {
  894. SSR_LOG_ERR(
  895. TASKID_Major_Client_And_Server_Log
  896. , TASKID_Minor_PreCreate_CPreCreateServices_QI
  897. , hr
  898. , L"[PC-PreCreate] Failed to create services object. Aborting."
  899. );
  900. STATUS_REPORT_REF_POSTCFG(
  901. TASKID_Major_Configure_Resources
  902. , TASKID_Minor_PreCreate_CPreCreateServices_QI
  903. , IDS_TASKID_MINOR_ERROR_CREATE_SERVICE
  904. , IDS_REF_MINOR_ERROR_CREATE_SERVICE
  905. , hr
  906. );
  907. goto Cleanup;
  908. }
  909. //
  910. // Update the UI layer.
  911. //
  912. hr = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_QUERYING_FOR_RESOURCE_DEPENDENCIES, &bstrNotification ) );
  913. if ( FAILED( hr ) )
  914. {
  915. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log, TASKID_Minor_PreCreate_LoadString_Querying, hr, L"Failed the load string for querying resource dependencies." );
  916. STATUS_REPORT_REF_POSTCFG(
  917. TASKID_Major_Configure_Resources
  918. , TASKID_Minor_PreCreate_LoadString_Querying
  919. , IDS_TASKID_MINOR_ERROR_LOADSTR_RES_DEP
  920. , IDS_REF_MINOR_ERROR_LOADSTR_RES_DEP
  921. , hr
  922. );
  923. goto Cleanup;
  924. }
  925. hr = THR( SendStatusReport( NULL,
  926. TASKID_Major_Configure_Resources,
  927. TASKID_Minor_Querying_For_Resource_Dependencies,
  928. 0,
  929. 5,
  930. 0,
  931. S_OK,
  932. bstrNotification,
  933. NULL,
  934. NULL
  935. ) );
  936. if ( hr == E_ABORT )
  937. goto Cleanup;
  938. // ignore failure
  939. //
  940. // Loop thru the resources, requesting the resources to PreCreate()
  941. // themselves. This will cause the resources to callback into the
  942. // services object and store class type and resource type information
  943. // as well as any required dependencies the resource might have.
  944. //
  945. for( ;; )
  946. {
  947. //
  948. // Cleanup. We put this here because of error conditions below.
  949. //
  950. TraceSysFreeString( bstrName );
  951. bstrName = NULL;
  952. TraceSysFreeString( bstrTemp );
  953. bstrTemp = NULL;
  954. if ( pccmri != NULL )
  955. {
  956. pccmri->Release();
  957. pccmri = NULL;
  958. }
  959. if ( pccmrc != NULL )
  960. {
  961. pccmrc->Release();
  962. pccmrc = NULL;
  963. }
  964. //
  965. // Ask to get the next resource.
  966. //
  967. hr = STHR( m_peccmr->Next( 1, &pccmri, NULL ) );
  968. if ( FAILED( hr ) )
  969. {
  970. SSR_LOG_ERR(
  971. TASKID_Major_Client_And_Server_Log
  972. , TASKID_Minor_PreCreate_EnumResources_Next
  973. , hr
  974. , L"[PC-PreCreate] Getting next managed resource failed. Aborting."
  975. );
  976. STATUS_REPORT_MINOR_REF_POSTCFG(
  977. TASKID_Minor_Querying_For_Resource_Dependencies
  978. , IDS_TASKID_MINOR_ERROR_MANAGED_RESOURCE
  979. , IDS_REF_MINOR_ERROR_MANAGED_RESOURCE
  980. , hr
  981. );
  982. goto Cleanup;
  983. }
  984. if ( hr == S_FALSE )
  985. {
  986. break; // exit loop
  987. }
  988. //
  989. // Retrieve its name for logging, etc. We will ultimately store this in the
  990. // resource entry to be reused (ownership will be transferred).
  991. //
  992. hr = THR( pccmri->GetName( &bstrName ) );
  993. if ( FAILED( hr ) )
  994. {
  995. SSR_LOG_ERR(
  996. TASKID_Major_Client_And_Server_Log
  997. , TASKID_Minor_PreCreate_EnumResources_GetName
  998. , hr
  999. , L"[PC-PreCreate] Failed to retrieve a resource's name. Skipping."
  1000. );
  1001. STATUS_REPORT_MINOR_REF_POSTCFG(
  1002. TASKID_Minor_Querying_For_Resource_Dependencies
  1003. , IDS_TASKID_MINOR_ERROR_GET_RESOURCE_NAME
  1004. , IDS_REF_MINOR_ERROR_GET_RESOURCE_NAME
  1005. , hr
  1006. );
  1007. continue;
  1008. }
  1009. //
  1010. // Check to see if the resource wants to be managed or not.
  1011. //
  1012. hr = STHR( pccmri->IsManaged() );
  1013. if ( FAILED( hr ) )
  1014. {
  1015. SSR_LOG1(
  1016. TASKID_Major_Client_And_Server_Log
  1017. , TASKID_Minor_PreCreate_EnumResources_IsManaged
  1018. , hr
  1019. , L"[PC-PreCreate] %1!ws!: Failed to determine if it is to be managed. Skipping."
  1020. , bstrNotification
  1021. , bstrName
  1022. );
  1023. STATUS_REPORT_MINOR_REF_POSTCFG1(
  1024. TASKID_Minor_Querying_For_Resource_Dependencies
  1025. , IDS_TASKID_MINOR_ERROR_DETERMINE_MANAGED
  1026. , IDS_REF_MINOR_ERROR_DETERMINE_MANAGED
  1027. , hr
  1028. , bstrName
  1029. );
  1030. continue;
  1031. }
  1032. if ( hr == S_FALSE )
  1033. {
  1034. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  1035. TASKID_Minor_PreCreate_EnumResources_IsManaged_False,
  1036. hr,
  1037. L"[PC-PreCreate] %1!ws!: Resource does not want to be managed. Skipping.",
  1038. bstrNotification,
  1039. bstrName
  1040. );
  1041. // No need to report this to the UI level.
  1042. continue;
  1043. }
  1044. /*
  1045. hr = STHR( HrIsLocalQuorum( bstrName ) );
  1046. if ( FAILED( hr ) )
  1047. {
  1048. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  1049. TASKID_Minor_PreCreate_EnumResources_IsLocalQuorum,
  1050. hr,
  1051. L"Error occured trying to determine if the resource was the local quorum resource.",
  1052. bstrNotification,
  1053. bstrName
  1054. );
  1055. continue;
  1056. } // if:
  1057. //
  1058. // Ignore the local quorum resource since it is special and won't need its own group.
  1059. //
  1060. if ( hr == S_OK )
  1061. {
  1062. continue;
  1063. } // if:
  1064. */
  1065. //
  1066. // Get the config interface for this resource (if any).
  1067. //
  1068. hr = THR( pccmri->TypeSafeQI( IClusCfgManagedResourceCfg, &pccmrc ) );
  1069. if ( FAILED( hr ) )
  1070. {
  1071. SSR_LOG1(
  1072. TASKID_Major_Client_And_Server_Log
  1073. , TASKID_Minor_PreCreate_EnumResources_QI_pccmrc
  1074. , hr
  1075. , L"[PC-PreCreate] %1!ws!: Failed QI for IClusCfgManagedResourceCfg. Skipping."
  1076. , bstrNotification
  1077. , bstrName
  1078. );
  1079. STATUS_REPORT_MINOR_REF_POSTCFG1(
  1080. TASKID_Minor_Querying_For_Resource_Dependencies
  1081. , IDS_TASKID_MINOR_ERROR_MANAGED_RES_CONFIG
  1082. , IDS_REF_MINOR_ERROR_MANAGED_RES_CONFIG
  1083. , hr
  1084. , bstrName
  1085. );
  1086. continue;
  1087. }
  1088. //
  1089. // Grow the resource list if nessecary.
  1090. //
  1091. if ( m_cResources == m_cAllocedResources )
  1092. {
  1093. ULONG idxNewCount = m_cAllocedResources + RESOURCE_INCREMENT;
  1094. CResourceEntry ** plistNew;
  1095. plistNew = (CResourceEntry **) TraceAlloc( 0, sizeof( CResourceEntry *) * idxNewCount );
  1096. if ( plistNew == NULL )
  1097. {
  1098. LogMsg( "[PC-PreCreate] Out of memory. Aborting." );
  1099. hr = THR( E_OUTOFMEMORY );
  1100. STATUS_REPORT_REF_POSTCFG(
  1101. TASKID_Minor_Querying_For_Resource_Dependencies
  1102. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_OutOfMemory
  1103. , IDS_TASKID_MINOR_ERROR_OUT_OF_MEMORY
  1104. , IDS_REF_MINOR_ERROR_OUT_OF_MEMORY
  1105. , hr
  1106. );
  1107. goto Cleanup;
  1108. }
  1109. CopyMemory( plistNew, m_rgpResources, sizeof(CResourceEntry *) * m_cAllocedResources );
  1110. TraceFree( m_rgpResources );
  1111. m_rgpResources = plistNew;
  1112. for ( ; m_cAllocedResources < idxNewCount; m_cAllocedResources ++ )
  1113. {
  1114. hr = THR( CResourceEntry::S_HrCreateInstance( &m_rgpResources[ m_cAllocedResources ], m_pcccb, m_lcid ) );
  1115. if ( FAILED( hr ) )
  1116. {
  1117. SSR_LOG_ERR(
  1118. TASKID_Major_Client_And_Server_Log
  1119. , TASKID_Minor_PreCreate_CResourceEntry
  1120. , hr
  1121. , L"[PC-PreCreate] Failed to create resource entry object. Aborting."
  1122. );
  1123. STATUS_REPORT_MINOR_REF_POSTCFG(
  1124. TASKID_Minor_Querying_For_Resource_Dependencies
  1125. , IDS_TASKID_MINOR_ERROR_CREATE_RESENTRY
  1126. , IDS_REF_MINOR_ERROR_CREATE_RESENTRY
  1127. , hr
  1128. );
  1129. goto Cleanup;
  1130. }
  1131. }
  1132. }
  1133. //
  1134. // Check to see if this resource is the quorum resource. If it is, point the services
  1135. // object to the quorum resource entry (m_idxQuorumResource).
  1136. //
  1137. hr = STHR( pccmri->IsQuorumResource() );
  1138. if ( hr == S_OK )
  1139. {
  1140. presentry = m_rgpResources[ m_idxQuorumResource ];
  1141. SSR_LOG1(
  1142. TASKID_Major_Client_And_Server_Log
  1143. , TASKID_PreCreate_EnumResources_IsQuorumDevice_S_OK
  1144. , hr
  1145. , L"[PC-PreCreate] %1!ws!: Setting this resource to be the quorum device."
  1146. , bstrNotification
  1147. , bstrName
  1148. );
  1149. STATUS_REPORT_MINOR_POSTCFG1(
  1150. TASKID_Minor_Querying_For_Resource_Dependencies
  1151. , IDS_TASKID_MINOR_SETTING_QUORUM_DEVICE
  1152. , hr
  1153. , bstrName
  1154. );
  1155. //
  1156. // We need to release the previous quorum's resource handle.
  1157. //
  1158. THR( presentry->SetHResource( NULL ) );
  1159. // We don't care if this fails... we'll overwrite it later.
  1160. //
  1161. // BUG 447944 - Quorum Resource is moved on an add.
  1162. // George Potts (GPotts) Sep 11 2001
  1163. //
  1164. // Set the quorum changed flag here. This flag indicates whether the quorum
  1165. // resource has changed or not. For initialization PostCfg assumes that it's
  1166. // a Local Quorum resource, which it will continue to use if no other
  1167. // quorum was later selected (via code (phys disk) or user (drop down box)).
  1168. // At this point in the code we've detected that the Local Quorum resource is
  1169. // not going to be the quorum. By setting this flag we indicate that PostCfg
  1170. // is to later call SetClusterQuorumResource. If we're not in create mode
  1171. // we use the quorum resource that the cluster started with, and the if
  1172. // statement that we're in updates our internal table to reflect that.
  1173. // If we are in create mode then we will need to update the quorum on the
  1174. // vanilla Local Quorum cluster that we always create first.
  1175. // If we don't put the if around the assignment below PostCfg wrongly thinks that
  1176. // the quorum has changed (when in fact it hasn't) and SetClusterQuorumResource
  1177. // will be called. The downsides of not using the if below are an uneccessary
  1178. // call is made and we call it with NULL so that the root path is overwritten.
  1179. //
  1180. if ( m_ecmCommitChangesMode == cmCREATE_CLUSTER )
  1181. {
  1182. m_fIsQuorumChanged = TRUE;
  1183. }
  1184. }
  1185. else
  1186. {
  1187. presentry = m_rgpResources[ m_cResources ];
  1188. if ( FAILED( hr ) )
  1189. {
  1190. SSR_LOG_ERR(
  1191. TASKID_Major_Client_And_Server_Log
  1192. , TASKID_PreCreate_EnumResources_IsQuorumDevice_Failed
  1193. , hr
  1194. , L"IsQuorumDevice() function failed."
  1195. );
  1196. STATUS_REPORT_MINOR_REF_POSTCFG1(
  1197. TASKID_Minor_Querying_For_Resource_Dependencies
  1198. , IDS_TASKID_MINOR_ERROR_IS_QUORUM_RESOURCE
  1199. , IDS_REF_MINOR_ERROR_IS_QUORUM_RESOURCE
  1200. , hr
  1201. , bstrName
  1202. );
  1203. }
  1204. }
  1205. //
  1206. // Setup the new entry.
  1207. //
  1208. hr = THR( presentry->SetAssociatedResource( pccmrc ) );
  1209. if ( FAILED( hr ) )
  1210. {
  1211. SSR_LOG_ERR(
  1212. TASKID_Major_Client_And_Server_Log
  1213. , TASKID_PreCreate_EnumResources_SetAssociatedResouce
  1214. , hr
  1215. , L"SetAssociatedResource() function failed."
  1216. );
  1217. STATUS_REPORT_MINOR_REF_POSTCFG1(
  1218. TASKID_Minor_Querying_For_Resource_Dependencies
  1219. , IDS_TASKID_MINOR_ERROR_SET_ASSOC_RESOURCE
  1220. , IDS_REF_MINOR_ERROR_SET_ASSOC_RESOURCE
  1221. , hr
  1222. , bstrName
  1223. );
  1224. continue;
  1225. }
  1226. //
  1227. // Make a local copy of bstrName for logging purposes then
  1228. // give ownership away.
  1229. //
  1230. bstrTemp = TraceSysAllocString( bstrName );
  1231. hr = THR( presentry->SetName( bstrName ) );
  1232. if ( FAILED( hr ) )
  1233. {
  1234. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log, TASKID_PreCreate_EnumResources_SetName, hr, L"SetName() function failed." );
  1235. STATUS_REPORT_MINOR_REF_POSTCFG1(
  1236. TASKID_Minor_Querying_For_Resource_Dependencies
  1237. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_NAME
  1238. , IDS_REF_MINOR_ERROR_SET_RESOURCE_NAME
  1239. , hr
  1240. , bstrName
  1241. );
  1242. continue;
  1243. }
  1244. // We gave ownership away when we called SetName() above.
  1245. bstrName = bstrTemp;
  1246. bstrTemp = NULL;
  1247. //
  1248. // Point the PreCreate services to the resource entry.
  1249. //
  1250. hr = THR( ppcr->SetEntry( presentry ) );
  1251. if ( FAILED( hr ) )
  1252. {
  1253. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log, TASKID_PreCreate_EnumResources_SetEntry, hr, L"SetEntry() function failed." );
  1254. STATUS_REPORT_MINOR_REF_POSTCFG1(
  1255. TASKID_Minor_Querying_For_Resource_Dependencies
  1256. , IDS_TASKID_MINOR_ERROR_SETENTRY
  1257. , IDS_REF_MINOR_ERROR_SETENTRY
  1258. , hr
  1259. , bstrName
  1260. );
  1261. continue;
  1262. }
  1263. //
  1264. // Ask the resource to configure itself. Every resource that wants to be
  1265. // created in the default cluster must implement PreCreate(). Those that
  1266. // return E_NOTIMPL will be ignored.
  1267. //
  1268. // Don't wrap - this can fail with E_NOTIMPL.
  1269. hr = pccmrc->PreCreate( punkServices );
  1270. if ( FAILED( hr ) )
  1271. {
  1272. if ( hr == E_NOTIMPL )
  1273. {
  1274. SSR_LOG1(
  1275. TASKID_Major_Client_And_Server_Log
  1276. , TASKID_Minor_PreCreate_PreCreate_E_NOTIMPL
  1277. , hr
  1278. , L"[PC-PreCreate] %1!ws!: Failed. Resource returned E_NOTIMPL. This resource will not be created. Skipping."
  1279. , bstrNotification
  1280. , bstrName
  1281. );
  1282. STATUS_REPORT_MINOR_REF_POSTCFG1(
  1283. TASKID_Minor_Querying_For_Resource_Dependencies
  1284. , IDS_TASKID_MINOR_ERROR_RES_NOT_CREATED
  1285. , IDS_REF_MINOR_ERROR_RES_NOT_CREATED
  1286. , hr
  1287. , bstrName
  1288. );
  1289. }
  1290. else
  1291. {
  1292. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  1293. TASKID_Minor_Resource_Failed_PreCreate,
  1294. hr,
  1295. L"[PC-PreCreate] %1!ws! failed PreCreate().",
  1296. bstrNotification,
  1297. bstrName
  1298. );
  1299. STATUS_REPORT_MINOR_REF_POSTCFG1(
  1300. TASKID_Minor_Querying_For_Resource_Dependencies
  1301. , IDS_TASKID_MINOR_RESOURCE_FAILED_PRECREATE
  1302. , IDS_REF_MINOR_RESOURCE_FAILED_PRECREATE
  1303. , hr
  1304. , bstrName
  1305. );
  1306. if ( hr == E_ABORT )
  1307. {
  1308. goto Cleanup;
  1309. // ignore failure
  1310. }
  1311. }
  1312. continue;
  1313. }
  1314. if ( presentry != m_rgpResources[ m_idxQuorumResource ] )
  1315. {
  1316. m_cResources ++;
  1317. }
  1318. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  1319. TASKID_Minor_PreCreate_Succeeded,
  1320. hr,
  1321. L"[PC-PreCreate] %1!ws!: Succeeded.",
  1322. bstrNotification,
  1323. bstrName
  1324. );
  1325. } // for: ever
  1326. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  1327. TASKID_Minor_PreCreate_Finished,
  1328. hr,
  1329. L"[PC-PreCreate] Finished.",
  1330. bstrNotification,
  1331. bstrName
  1332. );
  1333. #if defined(DEBUG)
  1334. // DebugDumpDepencyTree();
  1335. #endif
  1336. hr = THR( SendStatusReport( NULL,
  1337. TASKID_Major_Configure_Resources,
  1338. TASKID_Minor_Querying_For_Resource_Dependencies,
  1339. 0,
  1340. 5,
  1341. 5,
  1342. S_OK,
  1343. NULL, // don't need to update string
  1344. NULL,
  1345. NULL
  1346. ) );
  1347. if ( hr == E_ABORT )
  1348. goto Cleanup;
  1349. // ignore failure
  1350. hr = S_OK;
  1351. Cleanup:
  1352. TraceSysFreeString( bstrNotification );
  1353. TraceSysFreeString( bstrName );
  1354. TraceSysFreeString( bstrTemp );
  1355. if ( pccmri != NULL )
  1356. {
  1357. pccmri->Release();
  1358. }
  1359. if ( pccmrc != NULL )
  1360. {
  1361. pccmrc->Release();
  1362. }
  1363. if ( punkServices != NULL )
  1364. {
  1365. punkServices->Release();
  1366. }
  1367. if ( ppcr != NULL )
  1368. {
  1369. ppcr->Release();
  1370. }
  1371. HRETURN( hr );
  1372. } //*** CPostCfgManager::HrPreCreateResources
  1373. //////////////////////////////////////////////////////////////////////////////
  1374. //
  1375. // HRESULT
  1376. // CPostCfgManager::HrCreateGroups( void )
  1377. //
  1378. //////////////////////////////////////////////////////////////////////////////
  1379. HRESULT
  1380. CPostCfgManager::HrCreateGroups( void )
  1381. {
  1382. TraceFunc( "" );
  1383. HRESULT hr = S_OK;
  1384. DWORD dwStatus;
  1385. ULONG cGroup;
  1386. HGROUP hGroup = NULL;
  1387. CGroupHandle * pgh = NULL;
  1388. ULONG idxResource;
  1389. ULONG idxMatchDepedency;
  1390. ULONG idxMatchResource;
  1391. const CLSID * pclsidType = NULL;
  1392. const CLSID * pclsidClassType = NULL;
  1393. EDependencyFlags dfFlags;
  1394. CResourceEntry * presentry = NULL;
  1395. HCLUSENUM hClusEnum = NULL;
  1396. BSTR bstrGroupName = NULL;
  1397. BSTR bstrNotification = NULL;
  1398. DWORD sc;
  1399. HRESOURCE hCoreResourceArray[ 3 ] = { NULL, NULL, NULL};
  1400. HRESOURCE hCoreResource = NULL;
  1401. // Validate state
  1402. Assert( m_peccmr != NULL );
  1403. Assert( m_pccci != NULL );
  1404. Assert( m_idxLastStorage == 0 );
  1405. m_idxLastStorage = m_idxQuorumResource;
  1406. //
  1407. // Phase 1: Figure out the dependency tree.
  1408. //
  1409. hr = S_OK;
  1410. SSR_LOG_ERR(
  1411. TASKID_Major_Client_And_Server_Log
  1412. , TASKID_Minor_CreateGroups_Begin
  1413. , hr
  1414. , L"[PC-Grouping] Figuring out dependency tree to determine grouping."
  1415. );
  1416. STATUS_REPORT_POSTCFG(
  1417. TASKID_Major_Configure_Resources
  1418. , TASKID_Minor_CreateGroups_Begin
  1419. , IDS_TASKID_MINOR_FIGURE_DEPENDENCY_TREE
  1420. , hr
  1421. );
  1422. for ( idxResource = 0; idxResource < m_cResources; idxResource ++ )
  1423. {
  1424. CResourceEntry * presentryResource = m_rgpResources[ idxResource ];
  1425. ULONG cDependencies;
  1426. hr = THR( presentryResource->GetCountOfTypeDependencies( &cDependencies ) );
  1427. if ( FAILED( hr ) )
  1428. {
  1429. SSR_LOG_ERR(
  1430. TASKID_Major_Client_And_Server_Log
  1431. , TASKID_Minor_CreateGroups_GetCountOfTypeDependencies
  1432. , hr
  1433. , L"Failed to get the count of resource type dependencies."
  1434. );
  1435. STATUS_REPORT_MINOR_REF_POSTCFG(
  1436. TASKID_Minor_CreateGroups_Begin
  1437. , IDS_TASKID_MINOR_ERROR_COUNT_OF_DEPENDENCY
  1438. , IDS_REF_MINOR_ERROR_COUNT_OF_DEPENDENCY
  1439. , hr
  1440. );
  1441. continue;
  1442. }
  1443. for ( idxMatchDepedency = 0; idxMatchDepedency < cDependencies; idxMatchDepedency ++ )
  1444. {
  1445. BOOL fFoundMatch = FALSE;
  1446. const CLSID * pclsidMatchType;
  1447. EDependencyFlags dfMatchFlags;
  1448. hr = THR( presentryResource->GetTypeDependencyPtr( idxMatchDepedency,
  1449. &pclsidMatchType,
  1450. &dfMatchFlags
  1451. ) );
  1452. if ( FAILED( hr ) )
  1453. {
  1454. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log, TASKID_Minor_CreateGroups_GetTypeDependencyPtr, hr, L"Failed to get type dependency pointer" );
  1455. STATUS_REPORT_MINOR_REF_POSTCFG(
  1456. TASKID_Minor_CreateGroups_Begin
  1457. , IDS_TASKID_MINOR_ERROR_DEPENDENCY_PTR
  1458. , IDS_REF_MINOR_ERROR_DEPENDENCY_PTR
  1459. , hr
  1460. );
  1461. continue;
  1462. }
  1463. //
  1464. // See if it is one of the "well known" types.
  1465. //
  1466. //
  1467. // We special case storage class device because we want to spread as many
  1468. // resources across as many storage devices as possible. This helps prevent
  1469. // the ganging of resources into one large group.
  1470. //
  1471. if ( *pclsidMatchType == RESCLASSTYPE_StorageDevice )
  1472. {
  1473. //
  1474. // The below THR may fire in certain configurations. Please validate
  1475. // the configuration before removing the THR.
  1476. //
  1477. // If it returns E_FAIL, we should fall thru and attempt "normal"
  1478. // resource negociations.
  1479. //
  1480. hr = THR( HrAttemptToAssignStorageToResource( idxResource, dfMatchFlags ) );
  1481. if ( SUCCEEDED( hr ) )
  1482. {
  1483. fFoundMatch = TRUE;
  1484. }
  1485. else if ( FAILED( hr ) )
  1486. {
  1487. if ( hr != E_FAIL )
  1488. {
  1489. goto Cleanup;
  1490. }
  1491. }
  1492. }
  1493. else if ( *pclsidMatchType == RESTYPE_NetworkName )
  1494. {
  1495. BSTR bstrName = NULL;
  1496. hr = THR( HrFormatStringIntoBSTR( g_hInstance, IDS_NETNAMEFORMAT, &bstrName, m_cNetName ) );
  1497. if ( FAILED( hr ) )
  1498. {
  1499. SSR_LOG_ERR(
  1500. TASKID_Major_Client_And_Server_Log
  1501. , TASKID_Minor_CreateGroups_FormatString_NetName
  1502. , hr
  1503. , L"[PC-Grouping] Failed to create name for net name resource. Aborting."
  1504. );
  1505. STATUS_REPORT_MINOR_REF_POSTCFG(
  1506. TASKID_Minor_CreateGroups_Begin
  1507. , IDS_TASKID_MINOR_ERROR_NET_RESOURCE_NAME
  1508. , IDS_REF_MINOR_ERROR_NET_RESOURCE_NAME
  1509. , hr
  1510. );
  1511. goto Cleanup;
  1512. }
  1513. hr = THR( HrAddSpecialResource( bstrName,
  1514. &RESTYPE_NetworkName,
  1515. &RESCLASSTYPE_NetworkName
  1516. ) );
  1517. if ( FAILED( hr ) )
  1518. {
  1519. continue;
  1520. }
  1521. presentry = m_rgpResources[ m_cResources - 1 ];
  1522. // Net name depends on an IP address.
  1523. hr = THR( presentry->AddTypeDependency( &RESTYPE_IPAddress, dfSHARED ) );
  1524. if ( FAILED( hr ) )
  1525. {
  1526. SSR_LOG_ERR(
  1527. TASKID_Major_Client_And_Server_Log
  1528. , TASKID_Minor_CreateGroups_AddTypeDependency
  1529. , hr
  1530. , L"Failed to add type dependency."
  1531. );
  1532. STATUS_REPORT_MINOR_REF_POSTCFG(
  1533. TASKID_Minor_CreateGroups_Begin
  1534. , IDS_TASKID_MINOR_ERROR_TYPE_DEPENDENCY
  1535. , IDS_REF_MINOR_ERROR_TYPE_DEPENDENCY
  1536. , hr
  1537. );
  1538. continue;
  1539. }
  1540. hr = THR( presentry->AddDependent( idxResource, dfMatchFlags ) );
  1541. if ( FAILED( hr ) )
  1542. {
  1543. SSR_LOG_ERR(
  1544. TASKID_Major_Client_And_Server_Log
  1545. , TASKID_Minor_CreateGroups_Resource_AddDependent
  1546. , hr
  1547. , L"Failed to add a dependent entry."
  1548. );
  1549. STATUS_REPORT_MINOR_REF_POSTCFG(
  1550. TASKID_Minor_CreateGroups_Begin
  1551. , IDS_TASKID_MINOR_ERROR_ADD_DEPENDENT
  1552. , IDS_REF_MINOR_ERROR_ADD_DEPENDENT
  1553. , hr
  1554. );
  1555. continue;
  1556. }
  1557. fFoundMatch = TRUE;
  1558. }
  1559. else if ( *pclsidMatchType == RESTYPE_IPAddress )
  1560. {
  1561. BSTR bstrName = NULL;
  1562. hr = THR( HrFormatStringIntoBSTR( g_hInstance,
  1563. IDS_IPADDRESSFORMAT,
  1564. &bstrName,
  1565. FIRST_IPADDRESS( m_cIPAddress ),
  1566. SECOND_IPADDRESS( m_cIPAddress ),
  1567. THIRD_IPADDRESS( m_cIPAddress ),
  1568. FOURTH_IPADDRESS( m_cIPAddress )
  1569. ) );
  1570. if ( FAILED( hr ) )
  1571. {
  1572. SSR_LOG_ERR(
  1573. TASKID_Major_Client_And_Server_Log
  1574. , TASKID_Minor_CreateGroups_FormatString_IPAddress
  1575. , hr
  1576. , L"[PC-Grouping] Failed to create name for IP address resource. Aborting."
  1577. );
  1578. STATUS_REPORT_MINOR_REF_POSTCFG(
  1579. TASKID_Minor_CreateGroups_Begin
  1580. , IDS_TASKID_MINOR_ERROR_IP_RESOURCE_NAME
  1581. , IDS_REF_MINOR_ERROR_IP_RESOURCE_NAME
  1582. , hr
  1583. );
  1584. goto Cleanup;
  1585. }
  1586. hr = THR( HrAddSpecialResource( bstrName, &RESTYPE_IPAddress, &RESCLASSTYPE_IPAddress ) );
  1587. if ( FAILED( hr ) )
  1588. {
  1589. continue;
  1590. }
  1591. m_cIPAddress ++;
  1592. presentry = m_rgpResources[ m_cResources - 1 ];
  1593. hr = THR( presentry->AddDependent( idxResource, dfMatchFlags ) );
  1594. if ( FAILED( hr ) )
  1595. {
  1596. SSR_LOG_ERR(
  1597. TASKID_Major_Client_And_Server_Log
  1598. , TASKID_Minor_CreateGroups_Resource_AddDependent
  1599. , hr
  1600. , L"Failed to add a dependent entry."
  1601. );
  1602. STATUS_REPORT_MINOR_REF_POSTCFG(
  1603. TASKID_Minor_CreateGroups_Begin
  1604. , IDS_TASKID_MINOR_ERROR_ADD_DEPENDENT
  1605. , IDS_REF_MINOR_ERROR_ADD_DEPENDENT
  1606. , hr
  1607. );
  1608. continue;
  1609. }
  1610. fFoundMatch = TRUE;
  1611. }
  1612. else if ( *pclsidMatchType == RESTYPE_ClusterNetName )
  1613. {
  1614. presentry = m_rgpResources[ m_idxClusterName ];
  1615. hr = THR( presentry->AddDependent( idxResource, dfMatchFlags ) );
  1616. if ( FAILED( hr ) )
  1617. {
  1618. SSR_LOG_ERR(
  1619. TASKID_Major_Client_And_Server_Log
  1620. , TASKID_Minor_CreateGroups_NetName_AddDependent
  1621. , hr
  1622. , L"Failed to add a dependent entry."
  1623. );
  1624. STATUS_REPORT_MINOR_REF_POSTCFG(
  1625. TASKID_Minor_CreateGroups_Begin
  1626. , IDS_TASKID_MINOR_ERROR_ADD_DEPENDENT
  1627. , IDS_REF_MINOR_ERROR_ADD_DEPENDENT
  1628. , hr
  1629. );
  1630. continue;
  1631. }
  1632. fFoundMatch = TRUE;
  1633. }
  1634. else if ( *pclsidMatchType == RESTYPE_ClusterIPAddress )
  1635. {
  1636. presentry = m_rgpResources[ m_idxIPAddress ];
  1637. hr = THR( presentry->AddDependent( idxResource, dfMatchFlags ) );
  1638. if ( FAILED( hr ) )
  1639. {
  1640. SSR_LOG_ERR(
  1641. TASKID_Major_Client_And_Server_Log
  1642. , TASKID_Minor_CreateGroups_IPAddress_AddDependent
  1643. , hr
  1644. , L"Failed to add a dependent entry."
  1645. );
  1646. STATUS_REPORT_MINOR_REF_POSTCFG(
  1647. TASKID_Minor_CreateGroups_Begin
  1648. , IDS_TASKID_MINOR_ERROR_ADD_DEPENDENT
  1649. , IDS_REF_MINOR_ERROR_ADD_DEPENDENT
  1650. , hr
  1651. );
  1652. continue;
  1653. }
  1654. fFoundMatch = TRUE;
  1655. }
  1656. else if ( *pclsidMatchType == RESTYPE_ClusterQuorum )
  1657. {
  1658. presentry = m_rgpResources[ m_idxQuorumResource ];
  1659. hr = THR( presentry->AddDependent( idxResource, dfMatchFlags ) );
  1660. if ( FAILED( hr ) )
  1661. {
  1662. SSR_LOG_ERR(
  1663. TASKID_Major_Client_And_Server_Log
  1664. , TASKID_Minor_CreateGroups_QuorumDisk_AddDependent
  1665. , hr
  1666. , L"Failed to add a dependent entry."
  1667. );
  1668. STATUS_REPORT_MINOR_REF_POSTCFG(
  1669. TASKID_Minor_CreateGroups_Begin
  1670. , IDS_TASKID_MINOR_ERROR_ADD_DEPENDENT
  1671. , IDS_REF_MINOR_ERROR_ADD_DEPENDENT
  1672. , hr
  1673. );
  1674. continue;
  1675. }
  1676. fFoundMatch = TRUE;
  1677. }
  1678. //
  1679. // Check out the resources to see if it matches any of them.
  1680. //
  1681. if ( !fFoundMatch )
  1682. {
  1683. //
  1684. // We can always start at the quorum resource because the resource with indexes
  1685. // below that are handled in the special case code above.
  1686. //
  1687. for ( idxMatchResource = m_idxQuorumResource; idxMatchResource < m_cResources; idxMatchResource ++ )
  1688. {
  1689. presentry = m_rgpResources[ idxMatchResource ];
  1690. hr = THR( presentry->GetTypePtr( &pclsidType ) );
  1691. if ( FAILED( hr ) )
  1692. {
  1693. SSR_LOG_ERR(
  1694. TASKID_Major_Client_And_Server_Log
  1695. , TASKID_Minor_CreateGroups_GetTypePtr
  1696. , hr
  1697. , L"Failed to get resource type pointer."
  1698. );
  1699. STATUS_REPORT_MINOR_REF_POSTCFG(
  1700. TASKID_Minor_CreateGroups_Begin
  1701. , IDS_TASKID_MINOR_ERROR_GET_RESTYPE_PTR
  1702. , IDS_REF_MINOR_ERROR_GET_RESTYPE_PTR
  1703. , hr
  1704. );
  1705. continue;
  1706. }
  1707. hr = THR( presentry->GetClassTypePtr( &pclsidClassType ) );
  1708. if ( FAILED( hr ) )
  1709. {
  1710. SSR_LOG_ERR(
  1711. TASKID_Major_Client_And_Server_Log
  1712. , TASKID_Minor_CreateGroups_GetClassTypePtr
  1713. , hr
  1714. , L"Failed to get resource class type pointer."
  1715. );
  1716. STATUS_REPORT_MINOR_REF_POSTCFG(
  1717. TASKID_Minor_CreateGroups_Begin
  1718. , IDS_TASKID_MINOR_ERROR_GET_CLASSTYPE_PTR
  1719. , IDS_REF_MINOR_ERROR_GET_CLASSTYPE_PTR
  1720. , hr
  1721. );
  1722. continue;
  1723. }
  1724. hr = THR( presentry->GetFlags( &dfFlags ) );
  1725. if ( FAILED( hr ) )
  1726. {
  1727. SSR_LOG_ERR(
  1728. TASKID_Major_Client_And_Server_Log
  1729. , TASKID_Minor_CreateGroups_GetFlags
  1730. , hr
  1731. , L"Failed to get resource flags."
  1732. );
  1733. STATUS_REPORT_MINOR_REF_POSTCFG(
  1734. TASKID_Minor_CreateGroups_Begin
  1735. , IDS_TASKID_MINOR_ERROR_GET_RESOURCE_FLAGS
  1736. , IDS_REF_MINOR_ERROR_GET_RESOURCE_FLAGS
  1737. , hr
  1738. );
  1739. continue;
  1740. }
  1741. //
  1742. // Try matching it to the resource type.
  1743. //
  1744. if ( *pclsidType == *pclsidMatchType
  1745. || *pclsidClassType == *pclsidMatchType
  1746. )
  1747. {
  1748. if ( ! ( dfFlags & dfEXCLUSIVE )
  1749. || ( ( dfFlags & dfSHARED )
  1750. && ( dfMatchFlags & dfSHARED )
  1751. )
  1752. )
  1753. {
  1754. hr = THR( presentry->SetFlags( dfMatchFlags ) );
  1755. if ( FAILED( hr ) )
  1756. {
  1757. SSR_LOG_ERR(
  1758. TASKID_Major_Client_And_Server_Log
  1759. , TASKID_Minor_CreateGroups_SetFlags
  1760. , hr
  1761. , L"Failed to set resource flags."
  1762. );
  1763. STATUS_REPORT_MINOR_REF_POSTCFG(
  1764. TASKID_Minor_CreateGroups_Begin
  1765. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_FLAGS
  1766. , IDS_REF_MINOR_ERROR_SET_RESOURCE_FLAGS
  1767. , hr
  1768. );
  1769. continue;
  1770. }
  1771. hr = THR( presentry->AddDependent( idxResource, dfMatchFlags ) );
  1772. if ( FAILED( hr ) )
  1773. {
  1774. SSR_LOG_ERR(
  1775. TASKID_Major_Client_And_Server_Log
  1776. , TASKID_Minor_CreateGroups_Resource_AddDependent
  1777. , hr
  1778. , L"Failed to add a dependent entry."
  1779. );
  1780. STATUS_REPORT_MINOR_REF_POSTCFG(
  1781. TASKID_Minor_CreateGroups_Begin
  1782. , IDS_TASKID_MINOR_ERROR_ADD_DEPENDENT
  1783. , IDS_REF_MINOR_ERROR_ADD_DEPENDENT
  1784. , hr
  1785. );
  1786. continue;
  1787. }
  1788. fFoundMatch = TRUE;
  1789. break; // exit loop
  1790. }
  1791. }
  1792. } // for: idxMatchResource
  1793. } // if: not fFoundMatch
  1794. //
  1795. // If we didn't match the dependency, unmark the resource from being managed.
  1796. //
  1797. if ( !fFoundMatch )
  1798. {
  1799. BSTR bstrName;
  1800. IClusCfgManagedResourceInfo * pccmri;
  1801. IClusCfgManagedResourceCfg * pccmrc;
  1802. //
  1803. // KB: gpease 17-JUN-2000
  1804. // No need to free bstrName because the resource entry controls
  1805. // the lifetime - we're just borrowing it.
  1806. //
  1807. hr = THR( presentryResource->GetName( &bstrName ) );
  1808. if ( FAILED( hr ) )
  1809. {
  1810. SSR_LOG_ERR(
  1811. TASKID_Major_Client_And_Server_Log
  1812. , TASKID_Minor_CreateGroups_GetName
  1813. , hr
  1814. , L"Failed to get resource name."
  1815. );
  1816. STATUS_REPORT_MINOR_REF_POSTCFG(
  1817. TASKID_Minor_CreateGroups_Begin
  1818. , IDS_TASKID_MINOR_ERROR_GET_RESOURCE_NAME
  1819. , IDS_REF_MINOR_ERROR_GET_RESOURCE_NAME
  1820. , hr
  1821. );
  1822. continue;
  1823. }
  1824. hr = S_FALSE;
  1825. SSR_LOG1(
  1826. TASKID_Major_Client_And_Server_Log
  1827. , TASKID_Minor_CreateGroups_MissingDependent
  1828. , hr
  1829. , L"[PC-Grouping] %1!ws!: Missing dependent resource. This resource will not be configured."
  1830. , bstrNotification
  1831. , bstrName
  1832. );
  1833. STATUS_REPORT_MINOR_REF_POSTCFG1(
  1834. TASKID_Minor_CreateGroups_Begin
  1835. , IDS_TASKID_MINOR_ERROR_MISSING_DEPENDENT_RES
  1836. , IDS_REF_MINOR_ERROR_MISSING_DEPENDENT_RES
  1837. , hr
  1838. , bstrName
  1839. );
  1840. hr = THR( presentryResource->GetAssociatedResource( &pccmrc ) );
  1841. if ( FAILED( hr ) )
  1842. {
  1843. SSR_LOG_ERR(
  1844. TASKID_Major_Client_And_Server_Log
  1845. , TASKID_Minor_CreateGroups_GetAssociateResource
  1846. , hr
  1847. , L"Failed to get an associated resource."
  1848. );
  1849. STATUS_REPORT_MINOR_REF_POSTCFG1(
  1850. TASKID_Minor_CreateGroups_Begin
  1851. , IDS_TASKID_MINOR_ERROR_GET_ASSOC_RESOURCE
  1852. , IDS_REF_MINOR_ERROR_GET_ASSOC_RESOURCE
  1853. , hr
  1854. , bstrName
  1855. );
  1856. continue;
  1857. }
  1858. hr = THR( pccmrc->TypeSafeQI( IClusCfgManagedResourceInfo, &pccmri ) );
  1859. pccmrc->Release(); // release promptly.
  1860. if ( FAILED( hr ) )
  1861. {
  1862. SSR_LOG1(
  1863. TASKID_Major_Client_And_Server_Log
  1864. , TASKID_Minor_CreateGroups_QI_pccmri
  1865. , hr
  1866. , L"[PC-Grouping] %1!ws!: Resource failed to QI for IClusCfgManagedResourceInfo."
  1867. , bstrNotification
  1868. , bstrName
  1869. );
  1870. STATUS_REPORT_MINOR_REF_POSTCFG1(
  1871. TASKID_Minor_CreateGroups_Begin
  1872. , IDS_TASKID_MINOR_ERROR_MANAGED_RES_INFO
  1873. , IDS_REF_MINOR_ERROR_MANAGED_RES_INFO
  1874. , hr
  1875. , bstrName
  1876. );
  1877. continue;
  1878. }
  1879. hr = THR( pccmri->SetManaged( FALSE ) );
  1880. pccmri->Release(); // release promptly.
  1881. if ( FAILED( hr ) )
  1882. {
  1883. SSR_LOG1(
  1884. TASKID_Major_Client_And_Server_Log
  1885. , TASKID_Minor_CreateGroups_SetManaged
  1886. , hr
  1887. , L"[PC-Grouping] %1!ws!: Resource failed SetManaged( FALSE )."
  1888. , bstrNotification
  1889. , bstrName
  1890. );
  1891. STATUS_REPORT_MINOR_REF_POSTCFG1(
  1892. TASKID_Minor_CreateGroups_Begin
  1893. , IDS_TASKID_MINOR_ERROR_SET_MANAGED_FALSE
  1894. , IDS_REF_MINOR_ERROR_SET_MANAGED_FALSE
  1895. , hr
  1896. , bstrName
  1897. );
  1898. }
  1899. }
  1900. } // for: idxDepedency
  1901. } // for: idxResource
  1902. #if defined(DEBUG)
  1903. // DebugDumpDepencyTree();
  1904. #endif
  1905. hr = S_OK;
  1906. SSR_LOG_ERR(
  1907. TASKID_Major_Client_And_Server_Log
  1908. , TASKID_Minor_CreateGroups_Creating
  1909. , hr
  1910. , L"[PC-Grouping] Creating groups."
  1911. );
  1912. STATUS_REPORT_POSTCFG(
  1913. TASKID_Major_Configure_Resources
  1914. , TASKID_Minor_CreateGroups_Creating
  1915. , IDS_TASKID_MINOR_CREATING_GROUP
  1916. , hr
  1917. );
  1918. //
  1919. // For each of the core resources get the group that it's a member of and
  1920. // update our component to reflect that. No two core resources have to be
  1921. // in the same group.
  1922. //
  1923. sc = TW32( ResUtilGetCoreClusterResources( m_hCluster, &hCoreResourceArray[0], &hCoreResourceArray[1], &hCoreResourceArray[2] ) );
  1924. if ( sc != ERROR_SUCCESS )
  1925. {
  1926. hr = HRESULT_FROM_WIN32( sc );
  1927. SSR_LOG_ERR(
  1928. TASKID_Major_Client_And_Server_Log
  1929. , TASKID_Minor_CreateGroups_Get_CoreClusterGroup
  1930. , hr
  1931. , L"[PC-Grouping] Failed to get core resource handles. Aborting."
  1932. );
  1933. STATUS_REPORT_REF_POSTCFG(
  1934. TASKID_Minor_CreateGroups_Creating
  1935. , TASKID_Minor_CreateGroups_Get_CoreClusterGroup
  1936. , IDS_TASKID_MINOR_ERROR_GET_COREGROUP_HANDLE
  1937. , IDS_REF_MINOR_ERROR_GET_COREGROUP_HANDLE
  1938. , hr
  1939. );
  1940. goto Cleanup;
  1941. }
  1942. for ( idxResource = 0; idxResource <= m_idxQuorumResource; idxResource ++ )
  1943. {
  1944. hCoreResource = hCoreResourceArray[ idxResource ];
  1945. Assert( hCoreResource != NULL );
  1946. hr = THR( HrGetClusterResourceState( hCoreResource, NULL, &bstrGroupName, NULL ) );
  1947. if ( FAILED( hr ) )
  1948. {
  1949. goto Cleanup;
  1950. } // if:
  1951. CloseClusterResource( hCoreResource );
  1952. hCoreResource = NULL;
  1953. hGroup = OpenClusterGroup( m_hCluster, bstrGroupName );
  1954. if ( hGroup == NULL )
  1955. {
  1956. hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
  1957. SSR_LOG1(
  1958. TASKID_Major_Client_And_Server_Log
  1959. , TASKID_Minor_CreateGroups_OpenClusterGroup
  1960. , hr
  1961. , L"[PC-Grouping] Failed OpenClusterGroup('%1!ws!'). Aborting."
  1962. , bstrNotification
  1963. , bstrGroupName
  1964. );
  1965. STATUS_REPORT_REF_POSTCFG1(
  1966. TASKID_Minor_CreateGroups_Creating
  1967. , TASKID_Minor_CreateGroups_OpenClusterGroup
  1968. , IDS_TASKID_MINOR_ERROR_OPEN_GROUP
  1969. , IDS_REF_MINOR_ERROR_OPEN_GROUP
  1970. , hr
  1971. , bstrGroupName
  1972. );
  1973. goto Cleanup;
  1974. }
  1975. //
  1976. // Wrap it up and give ownership away.
  1977. //
  1978. hr = THR( CGroupHandle::S_HrCreateInstance( &pgh, hGroup ) );
  1979. if ( FAILED( hr ) )
  1980. {
  1981. SSR_LOG_ERR(
  1982. TASKID_Major_Client_And_Server_Log
  1983. , TASKID_Minor_CreateGroups_Create_CGroupHandle
  1984. , hr
  1985. , L"Failed to create group handle instance."
  1986. );
  1987. STATUS_REPORT_REF_POSTCFG1(
  1988. TASKID_Minor_CreateGroups_Creating
  1989. , TASKID_Minor_CreateGroups_Create_CGroupHandle
  1990. , IDS_TASKID_MINOR_ERROR_CREATE_GROUP_HANDLE
  1991. , IDS_REF_MINOR_ERROR_CREATE_GROUP_HANDLE
  1992. , hr
  1993. , bstrGroupName
  1994. );
  1995. goto Cleanup;
  1996. }
  1997. hGroup = NULL;
  1998. hr = THR( HrSetGroupOnResourceAndItsDependents( idxResource, pgh ) );
  1999. if ( FAILED( hr ) )
  2000. {
  2001. // If this failed it already updated the UI and logged an error.
  2002. goto Cleanup;
  2003. }
  2004. TraceSysFreeString( bstrGroupName );
  2005. bstrGroupName = NULL;
  2006. if ( pgh != NULL )
  2007. {
  2008. pgh->Release();
  2009. pgh = NULL;
  2010. }
  2011. } // for: each core resource update the view of what group it is in.
  2012. //
  2013. // Loop thru the resources looking for groups.
  2014. //
  2015. cGroup = 0;
  2016. for ( idxResource = m_idxQuorumResource + 1; idxResource < m_cResources; idxResource ++ )
  2017. {
  2018. CResourceEntry * presentryResource = m_rgpResources[ idxResource ];
  2019. ULONG cDependencies;
  2020. if ( pgh != NULL )
  2021. {
  2022. pgh->Release();
  2023. pgh = NULL;
  2024. }
  2025. hr = THR( presentryResource->GetCountOfTypeDependencies( &cDependencies ) );
  2026. if ( FAILED( hr ) )
  2027. {
  2028. SSR_LOG_ERR(
  2029. TASKID_Major_Client_And_Server_Log
  2030. , TASKID_Minor_CreateGroups_GetCountOfTypeDependencies2
  2031. , hr
  2032. , L"Failed to get the count of resource type dependencies."
  2033. );
  2034. STATUS_REPORT_MINOR_REF_POSTCFG(
  2035. TASKID_Minor_CreateGroups_Creating
  2036. , IDS_TASKID_MINOR_ERROR_COUNT_OF_DEPENDENCY
  2037. , IDS_REF_MINOR_ERROR_COUNT_OF_DEPENDENCY
  2038. , hr
  2039. );
  2040. continue;
  2041. }
  2042. //
  2043. // Don't consider resources that have indicated that the depend on
  2044. // somebody else.
  2045. //
  2046. if ( cDependencies != 0 )
  2047. {
  2048. continue;
  2049. }
  2050. //
  2051. // See if any of the dependent resource has already has a group assigned
  2052. // to it. This allows for multiple roots to be combined into a single
  2053. // group due to lower dependencies.
  2054. //
  2055. // Don't create a group for the local quoum resource!
  2056. hr = STHR( HrFindGroupFromResourceOrItsDependents( idxResource, &pgh ) );
  2057. if ( FAILED( hr ) )
  2058. {
  2059. continue;
  2060. }
  2061. if ( hr == S_FALSE )
  2062. {
  2063. //
  2064. // We need to create a new group.
  2065. //
  2066. //
  2067. // Create a name for our group.
  2068. //
  2069. for( ;; )
  2070. {
  2071. hr = THR( HrFormatStringIntoBSTR( g_hInstance, IDS_GROUP_X, &bstrGroupName, cGroup ) );
  2072. if ( FAILED( hr ) )
  2073. {
  2074. SSR_LOG_ERR(
  2075. TASKID_Major_Client_And_Server_Log
  2076. , TASKID_Minor_CreateGroups_FormatString_Group
  2077. , hr
  2078. , L"[PC-Grouping] Failed to create group name. Aborting."
  2079. );
  2080. STATUS_REPORT_MINOR_REF_POSTCFG(
  2081. TASKID_Minor_CreateGroups_Creating
  2082. , IDS_TASKID_MINOR_ERROR_CREATE_NAME
  2083. , IDS_REF_MINOR_ERROR_CREATE_NAME
  2084. , hr
  2085. );
  2086. goto Cleanup;
  2087. }
  2088. //
  2089. // Create the group in the cluster.
  2090. //
  2091. hGroup = CreateClusterGroup( m_hCluster, bstrGroupName );
  2092. if ( hGroup == NULL )
  2093. {
  2094. dwStatus = GetLastError();
  2095. switch ( dwStatus )
  2096. {
  2097. case ERROR_OBJECT_ALREADY_EXISTS:
  2098. cGroup ++;
  2099. break; // keep looping
  2100. default:
  2101. hr = HRESULT_FROM_WIN32( TW32( dwStatus ) );
  2102. SSR_LOG1(
  2103. TASKID_Major_Client_And_Server_Log
  2104. , TASKID_Minor_CreateGroups_CreateClusterGroup
  2105. , hr
  2106. , L"[PC-Grouping] %1!ws!: Failed to create group. Aborting."
  2107. , bstrNotification
  2108. , bstrGroupName
  2109. );
  2110. STATUS_REPORT_MINOR_REF_POSTCFG1(
  2111. TASKID_Minor_CreateGroups_Creating
  2112. , IDS_TASKID_MINOR_ERROR_CREATE_GROUP
  2113. , IDS_REF_MINOR_ERROR_CREATE_GROUP
  2114. , hr
  2115. , bstrGroupName
  2116. );
  2117. goto Cleanup;
  2118. }
  2119. }
  2120. else
  2121. {
  2122. break;
  2123. }
  2124. }
  2125. //
  2126. // Bring the group online to set its persistent state to Online.
  2127. //
  2128. dwStatus = TW32( OnlineClusterGroup( hGroup, NULL ) );
  2129. if ( dwStatus != ERROR_SUCCESS )
  2130. {
  2131. hr = HRESULT_FROM_WIN32( dwStatus );
  2132. SSR_LOG1(
  2133. TASKID_Major_Client_And_Server_Log
  2134. , TASKID_Minor_CreateGroups_OnlineClusterGroup
  2135. , hr
  2136. , L"[PC-Grouping] %1!ws!: Failed to bring group online. Aborting."
  2137. , bstrNotification
  2138. , bstrGroupName
  2139. );
  2140. STATUS_REPORT_MINOR_REF_POSTCFG1(
  2141. TASKID_Minor_CreateGroups_Creating
  2142. , IDS_TASKID_MINOR_ERROR_GROUP_ONLINE
  2143. , IDS_REF_MINOR_ERROR_GROUP_ONLINE
  2144. , hr
  2145. , bstrGroupName
  2146. );
  2147. goto Cleanup;
  2148. }
  2149. //
  2150. // Wrap the handle for ref counting.
  2151. //
  2152. hr = THR( CGroupHandle::S_HrCreateInstance( &pgh, hGroup ) );
  2153. if ( FAILED( hr ) )
  2154. {
  2155. SSR_LOG_ERR(
  2156. TASKID_Major_Client_And_Server_Log
  2157. , TASKID_Minor_CreateGroups_Create_CGroupHandle2
  2158. , hr
  2159. , L"Failed to create group handle instance."
  2160. );
  2161. STATUS_REPORT_MINOR_REF_POSTCFG1(
  2162. TASKID_Minor_CreateGroups_Creating
  2163. , IDS_TASKID_MINOR_ERROR_CREATE_GROUP_HANDLE
  2164. , IDS_REF_MINOR_ERROR_CREATE_GROUP_HANDLE
  2165. , hr
  2166. , bstrGroupName
  2167. );
  2168. goto Cleanup;
  2169. }
  2170. hGroup = NULL;
  2171. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  2172. TASKID_Minor_CreateGroups_Created,
  2173. hr,
  2174. L"[PC-Grouping] %1!ws!: Group created.",
  2175. bstrNotification,
  2176. bstrGroupName
  2177. );
  2178. cGroup ++;
  2179. }
  2180. hr = THR( HrSetGroupOnResourceAndItsDependents( idxResource, pgh ) );
  2181. if ( FAILED( hr ) )
  2182. {
  2183. continue;
  2184. }
  2185. } // for: idxResource
  2186. hr = S_OK;
  2187. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log,
  2188. TASKID_Minor_CreateGroups_Finished,
  2189. hr,
  2190. L"[PC-Grouping] Finished."
  2191. );
  2192. #if defined(DEBUG)
  2193. // DebugDumpDepencyTree();
  2194. #endif
  2195. Cleanup:
  2196. if ( hCoreResource != NULL )
  2197. {
  2198. CloseClusterResource( hCoreResource );
  2199. } // if:
  2200. TraceSysFreeString( bstrNotification );
  2201. TraceSysFreeString( bstrGroupName );
  2202. if ( hClusEnum != NULL )
  2203. {
  2204. TW32( ClusterCloseEnum( hClusEnum ) );
  2205. }
  2206. if ( hGroup != NULL )
  2207. {
  2208. BOOL fRet;
  2209. fRet = CloseClusterGroup( hGroup );
  2210. Assert( fRet );
  2211. }
  2212. if ( pgh != NULL )
  2213. {
  2214. pgh->Release();
  2215. }
  2216. HRETURN( hr );
  2217. } //*** CPostCfgManager::HrCreateGroups
  2218. //////////////////////////////////////////////////////////////////////////////
  2219. //
  2220. // HRESULT
  2221. // CPostCfgManager::HrCreateResources( void )
  2222. //
  2223. //////////////////////////////////////////////////////////////////////////////
  2224. HRESULT
  2225. CPostCfgManager::HrCreateResources( void )
  2226. {
  2227. TraceFunc( "" );
  2228. ULONG idxResource;
  2229. HRESULT hr;
  2230. BSTR bstrNotification = NULL;
  2231. // Validate state
  2232. Assert( m_peccmr != NULL );
  2233. Assert( m_pccci != NULL );
  2234. //
  2235. // Make a message using the name.
  2236. //
  2237. hr = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_CREATING_RESOURCE, &bstrNotification ) );
  2238. if ( FAILED( hr ) )
  2239. {
  2240. SSR_LOG_ERR(
  2241. TASKID_Major_Client_And_Server_Log
  2242. , TASKID_Minor_CreateResources_LoadString_Creating
  2243. , hr
  2244. , L"Failed to load a string for creating resource."
  2245. );
  2246. STATUS_REPORT_REF_POSTCFG(
  2247. TASKID_Major_Configure_Resources
  2248. , TASKID_Minor_CreateResources_LoadString_Creating
  2249. , IDS_TASKID_MINOR_ERROR_LOADSTRING
  2250. , IDS_REF_MINOR_ERROR_LOADSTRING
  2251. , hr
  2252. );
  2253. goto Cleanup;
  2254. }
  2255. //
  2256. // Tell the UI what we are doing.
  2257. //
  2258. hr = THR( SendStatusReport( NULL,
  2259. TASKID_Major_Configure_Resources,
  2260. TASKID_Minor_Creating_Resource,
  2261. 0,
  2262. m_cResources,
  2263. 0,
  2264. S_OK,
  2265. bstrNotification,
  2266. NULL,
  2267. NULL
  2268. ) );
  2269. if ( hr == E_ABORT )
  2270. {
  2271. goto Cleanup;
  2272. }
  2273. // ignore failure
  2274. hr = S_OK;
  2275. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log,
  2276. TASKID_Minor_CreateResources_Starting,
  2277. hr,
  2278. L"[PC-Create] Starting..."
  2279. );
  2280. for ( idxResource = m_idxQuorumResource; idxResource < m_cResources; idxResource ++ )
  2281. {
  2282. hr = THR( HrCreateResourceAndDependents( idxResource ) );
  2283. if ( FAILED( hr ) )
  2284. {
  2285. continue;
  2286. }
  2287. } // for: idxResource
  2288. hr = S_OK;
  2289. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log,
  2290. TASKID_Minor_CreateResources_Finished,
  2291. hr,
  2292. L"[PC-Create] Finished."
  2293. );
  2294. //
  2295. // Tell the UI what we are doing.
  2296. //
  2297. hr = THR( SendStatusReport( NULL,
  2298. TASKID_Major_Configure_Resources,
  2299. TASKID_Minor_Creating_Resource,
  2300. 0,
  2301. m_cResources,
  2302. m_cResources,
  2303. S_OK,
  2304. NULL,
  2305. NULL,
  2306. NULL
  2307. ) );
  2308. Cleanup:
  2309. TraceSysFreeString( bstrNotification );
  2310. HRETURN( hr );
  2311. } //*** CPostCfgManager::HrCreateResources
  2312. //////////////////////////////////////////////////////////////////////////////
  2313. //
  2314. // HRESULT
  2315. // CPostCfgManager::HrPostCreateResources( void )
  2316. //
  2317. //////////////////////////////////////////////////////////////////////////////
  2318. HRESULT
  2319. CPostCfgManager::HrPostCreateResources( void )
  2320. {
  2321. TraceFunc( "" );
  2322. HRESULT hr;
  2323. ULONG idxResource;
  2324. BSTR bstrNotification = NULL;
  2325. // Validate state
  2326. Assert( m_peccmr != NULL );
  2327. Assert( m_pccci != NULL );
  2328. //
  2329. // Tell the UI what's going on.
  2330. //
  2331. hr = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_STARTING_RESOURCES, &bstrNotification ) );
  2332. if ( FAILED( hr ) )
  2333. {
  2334. SSR_LOG_ERR(
  2335. TASKID_Major_Client_And_Server_Log
  2336. , TASKID_Minor_PostCreateResources_LoadString_Starting
  2337. , hr
  2338. , L"Failed the load string for starting resources."
  2339. );
  2340. STATUS_REPORT_REF_POSTCFG(
  2341. TASKID_Major_Configure_Resources
  2342. , TASKID_Minor_PostCreateResources_LoadString_Starting
  2343. , IDS_TASKID_MINOR_ERROR_LOADSTRING
  2344. , IDS_REF_MINOR_ERROR_LOADSTRING
  2345. , hr
  2346. );
  2347. goto Cleanup;
  2348. }
  2349. hr = THR( SendStatusReport( NULL,
  2350. TASKID_Major_Configure_Resources,
  2351. TASKID_Minor_Starting_Resources,
  2352. 0,
  2353. m_cResources + 2,
  2354. 0,
  2355. S_OK,
  2356. bstrNotification,
  2357. NULL,
  2358. NULL
  2359. ) );
  2360. if ( hr == E_ABORT )
  2361. {
  2362. goto Cleanup;
  2363. }
  2364. // ignore failure
  2365. hr = S_OK;
  2366. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log,
  2367. TASKID_Minor_PostCreateResources_Starting,
  2368. hr,
  2369. L"[PC-PostCreate] Starting..."
  2370. );
  2371. //
  2372. // Reset the configure flag on every resource.
  2373. //
  2374. for( idxResource = 0; idxResource < m_cResources ; idxResource ++ )
  2375. {
  2376. hr = THR( m_rgpResources[ idxResource ]->SetConfigured( FALSE ) );
  2377. if ( FAILED( hr ) )
  2378. {
  2379. continue;
  2380. }
  2381. } // for: idxResource
  2382. //
  2383. // Loop thru the resource calling PostCreate().
  2384. //
  2385. m_cResourcesConfigured = 0;
  2386. for( idxResource = 0; idxResource < m_cResources ; idxResource ++ )
  2387. {
  2388. hr = THR( HrPostCreateResourceAndDependents( idxResource ) );
  2389. if ( FAILED( hr ) )
  2390. {
  2391. continue;
  2392. }
  2393. } // for: ever
  2394. hr = S_OK;
  2395. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log,
  2396. TASKID_Minor_PostCreateResources_Finished,
  2397. hr,
  2398. L"[PC-PostCreate] Finished."
  2399. );
  2400. hr = THR( SendStatusReport( NULL,
  2401. TASKID_Major_Configure_Resources,
  2402. TASKID_Minor_Starting_Resources,
  2403. 0,
  2404. m_cResources + 2,
  2405. m_cResources + 2,
  2406. S_OK,
  2407. NULL, // don't need to change text
  2408. NULL,
  2409. NULL
  2410. ) );
  2411. if ( hr == E_ABORT )
  2412. goto Cleanup;
  2413. // ignore failure
  2414. Cleanup:
  2415. TraceSysFreeString( bstrNotification );
  2416. HRETURN( hr );
  2417. } //*** CPostCfgManager::HrPostCreateResources
  2418. //////////////////////////////////////////////////////////////////////////////
  2419. //++
  2420. //
  2421. // CPostCfgManager::HrEvictCleanupResources
  2422. //
  2423. // Description:
  2424. // Call the EvictCleanup method on each managed resource.
  2425. // This method is only called during an evict cleanup pass and there
  2426. // isn't any UI to display status reports.
  2427. //
  2428. // Arguments:
  2429. // None.
  2430. //
  2431. // Return Values:
  2432. // S_OK
  2433. // Other HRESULTs.
  2434. //
  2435. //--
  2436. //////////////////////////////////////////////////////////////////////////////
  2437. HRESULT
  2438. CPostCfgManager::HrEvictCleanupResources( void )
  2439. {
  2440. TraceFunc( "" );
  2441. HRESULT hr = S_OK;
  2442. IClusCfgManagedResourceInfo * pccmri = NULL;
  2443. IClusCfgManagedResourceCfg * pccmrc = NULL;
  2444. BSTR bstrName = NULL;
  2445. BSTR bstrMsg = NULL;
  2446. // Validate state
  2447. Assert( m_peccmr != NULL );
  2448. Assert( m_pccci != NULL );
  2449. hr = S_OK;
  2450. SSR_LOG_ERR(
  2451. TASKID_Major_Client_And_Server_Log
  2452. , TASKID_Minor_EvictCleanupResources_Starting
  2453. , hr
  2454. , L"[PC-EvictCleanup] Starting..."
  2455. );
  2456. //
  2457. // Make sure the enumerator is in the state we think it is.
  2458. //
  2459. hr = STHR( m_peccmr->Reset() );
  2460. if ( FAILED( hr ) )
  2461. {
  2462. SSR_LOG_ERR(
  2463. TASKID_Major_Client_And_Server_Log
  2464. , TASKID_Minor_EvictCleanup_Reset
  2465. , hr
  2466. , L"[PC-EvictCleanup] Failed to reset the enumerator."
  2467. );
  2468. STATUS_REPORT_REF_POSTCFG(
  2469. TASKID_Major_Configure_Resources
  2470. , TASKID_Minor_EvictCleanup_Reset
  2471. , IDS_TASKID_MINOR_ERROR_CLEANUP_RESET
  2472. , IDS_REF_MINOR_ERROR_CLEANUP_RESET
  2473. , hr
  2474. );
  2475. goto Cleanup;
  2476. } // if: failed to reset the enumerator
  2477. //
  2478. // Loop thru the resources calling EvictCleanup().
  2479. //
  2480. for( ;; )
  2481. {
  2482. //
  2483. // Cleanup. We put this here because of error conditions below.
  2484. //
  2485. TraceSysFreeString( bstrName );
  2486. bstrName = NULL;
  2487. if ( pccmri != NULL )
  2488. {
  2489. pccmri->Release();
  2490. pccmri = NULL;
  2491. }
  2492. if ( pccmrc != NULL )
  2493. {
  2494. pccmrc->Release();
  2495. pccmrc = NULL;
  2496. }
  2497. //
  2498. // Ask to get the next resource.
  2499. //
  2500. hr = STHR( m_peccmr->Next( 1, &pccmri, NULL ) );
  2501. if ( FAILED( hr ) )
  2502. {
  2503. SSR_LOG_ERR(
  2504. TASKID_Major_Client_And_Server_Log
  2505. , TASKID_Minor_EvictCleanup_EnumResources_Next
  2506. , hr
  2507. , L"[PC-EvictCleanup] Getting next managed resource failed. Aborting."
  2508. );
  2509. STATUS_REPORT_MINOR_REF_POSTCFG(
  2510. TASKID_Major_Configure_Resources
  2511. , IDS_TASKID_MINOR_ERROR_NEXT_MANAGED
  2512. , IDS_REF_MINOR_ERROR_NEXT_MANAGED
  2513. , hr
  2514. );
  2515. goto Cleanup;
  2516. } // if: failed to get the next entry from the enumerator
  2517. if ( hr == S_FALSE )
  2518. {
  2519. break; // exit loop
  2520. }
  2521. //
  2522. // Retrieve its name for logging, etc.
  2523. //
  2524. hr = THR( pccmri->GetName( &bstrName ) );
  2525. if ( FAILED( hr ) )
  2526. {
  2527. SSR_LOG_ERR(
  2528. TASKID_Major_Client_And_Server_Log
  2529. , TASKID_Minor_EvictCleanup_EnumResources_GetName
  2530. , hr
  2531. , L"[PC-EvictCleanup] Failed to retrieve a resource's name. Skipping."
  2532. );
  2533. STATUS_REPORT_MINOR_REF_POSTCFG(
  2534. TASKID_Major_Configure_Resources
  2535. , IDS_TASKID_MINOR_ERROR_GET_RESOURCE_NAME
  2536. , IDS_REF_MINOR_ERROR_GET_RESOURCE_NAME
  2537. , hr
  2538. );
  2539. continue;
  2540. } // if: failed to get the name of the resource
  2541. TraceMemoryAddBSTR( bstrName );
  2542. //
  2543. // Get the config interface for this resource (if any).
  2544. //
  2545. hr = THR( pccmri->TypeSafeQI( IClusCfgManagedResourceCfg, &pccmrc ) );
  2546. if ( FAILED( hr ) )
  2547. {
  2548. SSR_LOG1(
  2549. TASKID_Major_Client_And_Server_Log
  2550. , TASKID_Minor_EvictCleanup_EnumResources_QI_pccmrc
  2551. , hr
  2552. , L"[PC-EvictCleanup] %1!ws!: Failed QI for IClusCfgManagedResourceCfg. Skipping."
  2553. , bstrMsg
  2554. , bstrName
  2555. );
  2556. STATUS_REPORT_MINOR_REF_POSTCFG1(
  2557. TASKID_Major_Configure_Resources
  2558. , IDS_TASKID_MINOR_ERROR_MANAGED_RES_CONFIG
  2559. , IDS_REF_MINOR_ERROR_MANAGED_RES_CONFIG
  2560. , hr
  2561. , bstrName
  2562. );
  2563. continue;
  2564. } // if: failed to get the IClusCfgManagedResourceCfg interface
  2565. //
  2566. // Ask the resource to clean itself up.
  2567. //
  2568. // Don't wrap - this can fail with E_NOTIMPL.
  2569. hr = pccmrc->Evict( NULL );
  2570. if ( FAILED( hr ) )
  2571. {
  2572. if ( hr == E_NOTIMPL )
  2573. {
  2574. SSR_LOG1(
  2575. TASKID_Major_Client_And_Server_Log
  2576. , TASKID_Minor_EvictCleanup_E_NOTIMPL
  2577. , hr
  2578. , L"[PC-EvictCleanup] %1!ws!: Failed. Resource returned E_NOTIMPL. This resource will not be cleaned up. Skipping."
  2579. , bstrMsg
  2580. , bstrName
  2581. );
  2582. STATUS_REPORT_MINOR_REF_POSTCFG1(
  2583. TASKID_Major_Configure_Resources
  2584. , IDS_TASKID_MINOR_ERROR_RES_NOT_CLEANED
  2585. , IDS_REF_MINOR_ERROR_RES_NOT_CLEANED
  2586. , hr
  2587. , bstrName
  2588. );
  2589. } // if: resource doesn't support this method
  2590. else
  2591. {
  2592. SSR_LOG1(
  2593. TASKID_Major_Client_And_Server_Log
  2594. , TASKID_Minor_Resource_Failed_Evict
  2595. , hr
  2596. , L"[PC-EvictCleanup] %1!ws! failed Evict()."
  2597. , bstrMsg
  2598. , bstrName
  2599. );
  2600. STATUS_REPORT_MINOR_REF_POSTCFG1(
  2601. TASKID_Major_Configure_Resources
  2602. , IDS_TASKID_MINOR_ERROR_EVICT
  2603. , IDS_REF_MINOR_ERROR_EVICT
  2604. , hr
  2605. , bstrName
  2606. );
  2607. } // else: resource's Evict method failed
  2608. continue;
  2609. } // if: Evict on resource failed
  2610. SSR_LOG1(
  2611. TASKID_Major_Client_And_Server_Log
  2612. , TASKID_Minor_EvictCleanup_Succeeded
  2613. , hr
  2614. , L"[PC-EvictCleanup] %1!ws!: Succeeded."
  2615. , bstrMsg
  2616. , bstrName
  2617. );
  2618. } // for ever looping through the managed resource enumerator
  2619. // Failures don't really matter. We don't want them to abort the
  2620. // evict cleanup process.
  2621. hr = S_OK;
  2622. SSR_LOG_ERR(
  2623. TASKID_Major_Client_And_Server_Log
  2624. , TASKID_Minor_EvictCleanupResources_Finishing
  2625. , hr
  2626. , L"[PC-EvictCleanup] Finished."
  2627. );
  2628. Cleanup:
  2629. TraceSysFreeString( bstrName );
  2630. TraceSysFreeString( bstrMsg );
  2631. if ( pccmrc != NULL )
  2632. {
  2633. pccmrc->Release();
  2634. }
  2635. if ( pccmri != NULL )
  2636. {
  2637. pccmri->Release();
  2638. }
  2639. HRETURN( hr );
  2640. } //*** CPostCfgManager::HrEvictCleanupResources
  2641. //////////////////////////////////////////////////////////////////////////////
  2642. //
  2643. // HRESULT
  2644. // CPostCfgManager::HrFindNextSharedStorage(
  2645. // ULONG idxSeedIn,
  2646. // ULONG * pidxOut
  2647. // )
  2648. //
  2649. //////////////////////////////////////////////////////////////////////////////
  2650. HRESULT
  2651. CPostCfgManager::HrFindNextSharedStorage(
  2652. ULONG * pidxInout
  2653. )
  2654. {
  2655. TraceFunc( "" );
  2656. HRESULT hr;
  2657. ULONG idxNextDiskResource;
  2658. const CLSID * pclsidClassType;
  2659. CResourceEntry * presentry;
  2660. EDependencyFlags dfFlags;
  2661. BOOL fFirstPass = TRUE;
  2662. Assert( pidxInout != NULL );
  2663. for( idxNextDiskResource = *pidxInout + 1
  2664. ; fFirstPass && idxNextDiskResource != *pidxInout
  2665. ; idxNextDiskResource ++
  2666. )
  2667. {
  2668. if ( idxNextDiskResource >= m_cResources )
  2669. {
  2670. fFirstPass = FALSE;
  2671. idxNextDiskResource = m_idxQuorumResource;
  2672. }
  2673. presentry = m_rgpResources[ idxNextDiskResource ];
  2674. hr = THR( presentry->GetClassTypePtr( &pclsidClassType ) );
  2675. if ( FAILED( hr ) )
  2676. {
  2677. SSR_LOG_ERR(
  2678. TASKID_Major_Client_And_Server_Log
  2679. , TASKID_Minor_FindNextSharedStorage_GetClassTypePtr
  2680. , hr
  2681. , L"Failed to get resource class type pointer."
  2682. );
  2683. STATUS_REPORT_MINOR_REF_POSTCFG(
  2684. TASKID_Major_Configure_Resources
  2685. , IDS_TASKID_MINOR_ERROR_GET_CLASSTYPE_PTR
  2686. , IDS_REF_MINOR_ERROR_GET_CLASSTYPE_PTR
  2687. , hr
  2688. );
  2689. continue;
  2690. }
  2691. // Skip non-storage class devices
  2692. if ( *pclsidClassType != RESCLASSTYPE_StorageDevice )
  2693. continue;
  2694. hr = THR( presentry->GetFlags( &dfFlags ) );
  2695. if ( FAILED( hr ) )
  2696. {
  2697. SSR_LOG_ERR(
  2698. TASKID_Major_Client_And_Server_Log
  2699. , TASKID_Minor_FindNextSharedStorage_GetFlags
  2700. , hr
  2701. , L"Failed to get resource flags."
  2702. );
  2703. STATUS_REPORT_MINOR_REF_POSTCFG(
  2704. TASKID_Major_Configure_Resources
  2705. , IDS_TASKID_MINOR_ERROR_GET_RESOURCE_FLAGS
  2706. , IDS_REF_MINOR_ERROR_GET_RESOURCE_FLAGS
  2707. , hr
  2708. );
  2709. continue;
  2710. }
  2711. if ( ! ( dfFlags & dfEXCLUSIVE ) )
  2712. {
  2713. *pidxInout = idxNextDiskResource;
  2714. hr = S_OK;
  2715. goto Cleanup;
  2716. }
  2717. } // for: fFirstPass && idxNextDiskResource
  2718. hr = THR( E_FAIL );
  2719. Cleanup:
  2720. HRETURN( hr );
  2721. } //*** CPostCfgManager::HrFindNextSharedStorage
  2722. //////////////////////////////////////////////////////////////////////////////
  2723. //
  2724. // HRESULT
  2725. // CPostCfgManager::HrAttemptToAssignStorageToResource(
  2726. // ULONG idxResource
  2727. // )
  2728. //
  2729. //////////////////////////////////////////////////////////////////////////////
  2730. HRESULT
  2731. CPostCfgManager::HrAttemptToAssignStorageToResource(
  2732. ULONG idxResourceIn,
  2733. EDependencyFlags dfResourceFlagsIn
  2734. )
  2735. {
  2736. TraceFunc1( "idxResource = %u", idxResourceIn );
  2737. HRESULT hr;
  2738. ULONG idxStorage;
  2739. CResourceEntry * presentry;
  2740. //
  2741. // Find the next available shared storage resource.
  2742. //
  2743. idxStorage = m_idxLastStorage;
  2744. hr = THR( HrFindNextSharedStorage( &idxStorage ) );
  2745. if ( FAILED( hr ) )
  2746. goto Cleanup;
  2747. //
  2748. // If the resource wants exclusive rights the the disk, then the quorum
  2749. // resource can not be used. The quorum device must always have SHARED
  2750. // access to it.
  2751. //
  2752. if ( ( dfResourceFlagsIn & dfEXCLUSIVE )
  2753. && ( idxStorage == m_idxQuorumResource )
  2754. )
  2755. {
  2756. hr = THR( HrFindNextSharedStorage( &idxStorage ) );
  2757. if ( idxStorage == m_idxQuorumResource )
  2758. {
  2759. //
  2760. // There must not be anymore storage devices available for exclusive
  2761. // access. Return failure.
  2762. //
  2763. hr = THR( E_FAIL );
  2764. SSR_LOG_ERR(
  2765. TASKID_Major_Client_And_Server_Log
  2766. , TASKID_Minor_HrAttemptToAssignStorageToResource_NoMoreStorage
  2767. , hr
  2768. , L"There must not be anymore storage devices available for exclusive access."
  2769. );
  2770. STATUS_REPORT_REF_POSTCFG(
  2771. TASKID_Major_Configure_Resources
  2772. , TASKID_Minor_HrAttemptToAssignStorageToResource_NoMoreStorage
  2773. , IDS_TASKID_MINOR_ERROR_AVAILABLE_STORAGE
  2774. , IDS_REF_MINOR_ERROR_AVAILABLE_STORAGE
  2775. , hr
  2776. );
  2777. goto Cleanup;
  2778. }
  2779. }
  2780. presentry = m_rgpResources[ idxStorage ];
  2781. //
  2782. // Set the dependency flags.
  2783. //
  2784. hr = THR( presentry->SetFlags( dfResourceFlagsIn ) );
  2785. if ( FAILED( hr ) )
  2786. {
  2787. SSR_LOG_ERR(
  2788. TASKID_Major_Client_And_Server_Log
  2789. , TASKID_Minor_HrAttemptToAssignStorageToResource_SetFlags
  2790. , hr
  2791. , L"Failed to set the dependency flags."
  2792. );
  2793. STATUS_REPORT_REF_POSTCFG(
  2794. TASKID_Major_Configure_Resources
  2795. , TASKID_Minor_HrAttemptToAssignStorageToResource_SetFlags
  2796. , IDS_TASKID_MINOR_ERROR_SET_RES_DEP_FLAGS
  2797. , IDS_REF_MINOR_ERROR_SET_RES_DEP_FLAGS
  2798. , hr
  2799. );
  2800. goto Cleanup;
  2801. }
  2802. //
  2803. // If the resource wants exclusive access to the storage resource, move
  2804. // any existing SHARED dependents to another resource. There will always
  2805. // be at least one SHARED resource because the quorum disk can't not be
  2806. // assigned to EXCLUSIVE access.
  2807. //
  2808. if ( dfResourceFlagsIn & dfEXCLUSIVE )
  2809. {
  2810. ULONG idxNewStorage = idxStorage;
  2811. hr = THR( HrFindNextSharedStorage( &idxNewStorage ) );
  2812. if ( FAILED( hr ) )
  2813. goto Cleanup;
  2814. hr = THR( HrMovedDependentsToAnotherResource( idxStorage, idxNewStorage ) );
  2815. if ( FAILED( hr ) )
  2816. goto Cleanup;
  2817. }
  2818. //
  2819. // Add the resource as a dependent of this storage resource.
  2820. //
  2821. hr = THR( presentry->AddDependent( idxResourceIn, dfResourceFlagsIn ) );
  2822. if ( FAILED( hr ) )
  2823. {
  2824. SSR_LOG_ERR(
  2825. TASKID_Major_Client_And_Server_Log
  2826. , TASKID_Minor_HrAttemptToAssignStorageToResource_AddDependent
  2827. , hr
  2828. , L"Failed to add a dependent."
  2829. );
  2830. STATUS_REPORT_REF_POSTCFG(
  2831. TASKID_Major_Configure_Resources
  2832. , TASKID_Minor_HrAttemptToAssignStorageToResource_AddDependent
  2833. , IDS_TASKID_MINOR_ERROR_ADD_DEPENDENT
  2834. , IDS_REF_MINOR_ERROR_ADD_DEPENDENT
  2835. , hr
  2836. );
  2837. goto Cleanup;
  2838. }
  2839. m_idxLastStorage = idxStorage;
  2840. hr = S_OK;
  2841. Cleanup:
  2842. HRETURN( hr );
  2843. } //*** CPostCfgManager::HrAttemptToAssignStorageToResource
  2844. //////////////////////////////////////////////////////////////////////////////
  2845. //
  2846. // HRESULT
  2847. // CPostCfgManager::HrMovedDependentsToAnotherResource(
  2848. // ULONG idxSourceIn,
  2849. // ULONG idxDestIn
  2850. // )
  2851. //
  2852. //////////////////////////////////////////////////////////////////////////////
  2853. HRESULT
  2854. CPostCfgManager::HrMovedDependentsToAnotherResource(
  2855. ULONG idxSourceIn,
  2856. ULONG idxDestIn
  2857. )
  2858. {
  2859. TraceFunc( "" );
  2860. HRESULT hr;
  2861. ULONG cDependents;
  2862. ULONG idxDependent;
  2863. EDependencyFlags dfFlags;
  2864. CResourceEntry * presentrySrc;
  2865. CResourceEntry * presentryDst;
  2866. //
  2867. // Move the shared resources to another shared disk.
  2868. //
  2869. presentrySrc = m_rgpResources[ idxSourceIn ];
  2870. presentryDst = m_rgpResources[ idxDestIn ];
  2871. hr = THR( presentrySrc->GetCountOfDependents( &cDependents ) );
  2872. if ( FAILED( hr ) )
  2873. {
  2874. SSR_LOG_ERR(
  2875. TASKID_Major_Client_And_Server_Log
  2876. , TASKID_Minor_HrMovedDependentsToAnotherResource_GetCountOfDependents
  2877. , hr
  2878. , L"Failed to get the count of dependents."
  2879. );
  2880. STATUS_REPORT_REF_POSTCFG(
  2881. TASKID_Major_Configure_Resources
  2882. , TASKID_Minor_HrMovedDependentsToAnotherResource_GetCountOfDependents
  2883. , IDS_TASKID_MINOR_ERROR_COUNT_OF_DEPENDENTS
  2884. , IDS_REF_MINOR_ERROR_COUNT_OF_DEPENDENTS
  2885. , hr
  2886. );
  2887. goto Cleanup;
  2888. }
  2889. for ( ; cDependents != 0 ; )
  2890. {
  2891. cDependents --;
  2892. hr = THR( presentrySrc->GetDependent( cDependents, &idxDependent, &dfFlags ) );
  2893. if ( FAILED( hr ) )
  2894. {
  2895. SSR_LOG_ERR(
  2896. TASKID_Major_Client_And_Server_Log
  2897. , TASKID_Minor_HrMovedDependentsToAnotherResource_GetDependent
  2898. , hr
  2899. , L"Failed to get a resource dependent."
  2900. );
  2901. STATUS_REPORT_MINOR_REF_POSTCFG(
  2902. TASKID_Major_Configure_Resources
  2903. , IDS_TASKID_MINOR_ERROR_GET_DEPENDENT
  2904. , IDS_REF_MINOR_ERROR_GET_DEPENDENT
  2905. , hr
  2906. );
  2907. goto Cleanup;
  2908. }
  2909. hr = THR( presentryDst->AddDependent( idxDependent, dfFlags ) );
  2910. if ( FAILED( hr ) )
  2911. {
  2912. SSR_LOG_ERR(
  2913. TASKID_Major_Client_And_Server_Log
  2914. , TASKID_Minor_HrMovedDependentsToAnotherResource_AddDependent
  2915. , hr
  2916. , L"Failed to add a dependent."
  2917. );
  2918. STATUS_REPORT_MINOR_REF_POSTCFG(
  2919. TASKID_Major_Configure_Resources
  2920. , IDS_TASKID_MINOR_ERROR_ADD_DEPENDENT
  2921. , IDS_REF_MINOR_ERROR_ADD_DEPENDENT
  2922. , hr
  2923. );
  2924. goto Cleanup;
  2925. }
  2926. } // for: cDependents
  2927. hr = THR( presentrySrc->ClearDependents() );
  2928. if ( FAILED( hr ) )
  2929. {
  2930. SSR_LOG_ERR(
  2931. TASKID_Major_Client_And_Server_Log
  2932. , TASKID_Minor_HrMovedDependentsToAnotherResource_ClearDependents
  2933. , hr
  2934. , L"Failed to clear the resource dependents."
  2935. );
  2936. STATUS_REPORT_REF_POSTCFG(
  2937. TASKID_Major_Configure_Resources
  2938. , TASKID_Minor_HrMovedDependentsToAnotherResource_ClearDependents
  2939. , IDS_TASKID_MINOR_ERROR_CLEAR_DEPENDENT
  2940. , IDS_REF_MINOR_ERROR_CLEAR_DEPENDENT
  2941. , hr
  2942. );
  2943. goto Cleanup;
  2944. }
  2945. Cleanup:
  2946. HRETURN( hr );
  2947. } //*** CPostCfgManager::HrMovedDependentsToAnotherResource
  2948. //////////////////////////////////////////////////////////////////////////////
  2949. //
  2950. // HRESULT
  2951. // CPostCfgManager::HrSetGroupOnResourceAndItsDependents(
  2952. // ULONG idxResourceIn,
  2953. // CGroupHandle * pghIn
  2954. // )
  2955. //
  2956. //////////////////////////////////////////////////////////////////////////////
  2957. HRESULT
  2958. CPostCfgManager::HrSetGroupOnResourceAndItsDependents(
  2959. ULONG idxResourceIn,
  2960. CGroupHandle * pghIn
  2961. )
  2962. {
  2963. TraceFunc1( "idxResourceIn = %u", idxResourceIn );
  2964. HRESULT hr;
  2965. ULONG cDependents;
  2966. ULONG idxDependent;
  2967. EDependencyFlags dfDependent;
  2968. CResourceEntry * presentry;
  2969. presentry = m_rgpResources[ idxResourceIn ];
  2970. hr = THR( presentry->SetGroupHandle( pghIn ) );
  2971. if ( FAILED( hr ) )
  2972. {
  2973. SSR_LOG_ERR(
  2974. TASKID_Major_Client_And_Server_Log
  2975. , TASKID_Minor_HrSetGroupOnResourceAndItsDependents_SetGroupHandle
  2976. , hr
  2977. , L"Failed to set group handle."
  2978. );
  2979. STATUS_REPORT_REF_POSTCFG(
  2980. TASKID_Major_Configure_Resources
  2981. , TASKID_Minor_HrSetGroupOnResourceAndItsDependents_SetGroupHandle
  2982. , IDS_TASKID_MINOR_ERROR_SET_GROUP_HANDLE
  2983. , IDS_REF_MINOR_ERROR_SET_GROUP_HANDLE
  2984. , hr
  2985. );
  2986. goto Cleanup;
  2987. }
  2988. //
  2989. // Follow the depents list.
  2990. //
  2991. hr = THR( presentry->GetCountOfDependents( &cDependents ) );
  2992. if ( FAILED( hr ) )
  2993. {
  2994. SSR_LOG_ERR(
  2995. TASKID_Major_Client_And_Server_Log
  2996. , TASKID_Minor_HrSetGroupOnResourceAndItsDependents_GetCountOfDependents
  2997. , hr
  2998. , L"Failed to get the count of dependents."
  2999. );
  3000. STATUS_REPORT_REF_POSTCFG(
  3001. TASKID_Major_Configure_Resources
  3002. , TASKID_Minor_HrSetGroupOnResourceAndItsDependents_GetCountOfDependents
  3003. , IDS_TASKID_MINOR_ERROR_COUNT_OF_DEPENDENTS
  3004. , IDS_REF_MINOR_ERROR_COUNT_OF_DEPENDENTS
  3005. , hr
  3006. );
  3007. goto Cleanup;
  3008. }
  3009. for ( ; cDependents != 0 ; )
  3010. {
  3011. cDependents --;
  3012. hr = THR( presentry->GetDependent( cDependents, &idxDependent, &dfDependent ) );
  3013. if ( FAILED( hr ) )
  3014. {
  3015. SSR_LOG_ERR(
  3016. TASKID_Major_Client_And_Server_Log
  3017. , TASKID_Minor_HrSetGroupOnResourceAndItsDependents_GetDependent
  3018. , hr
  3019. , L"Failed to get a resource dependent."
  3020. );
  3021. STATUS_REPORT_MINOR_REF_POSTCFG(
  3022. TASKID_Major_Configure_Resources
  3023. , IDS_TASKID_MINOR_ERROR_GET_DEPENDENT
  3024. , IDS_REF_MINOR_ERROR_GET_DEPENDENT
  3025. , hr
  3026. );
  3027. continue;
  3028. }
  3029. hr = THR( HrSetGroupOnResourceAndItsDependents( idxDependent, pghIn ) );
  3030. if ( FAILED( hr ) )
  3031. {
  3032. continue;
  3033. }
  3034. } // for: cDependents
  3035. hr = S_OK;
  3036. Cleanup:
  3037. HRETURN( hr );
  3038. } //*** CPostCfgManager::HrSetGroupOnResourceAndItsDependents
  3039. //////////////////////////////////////////////////////////////////////////////
  3040. //
  3041. // HRESULT
  3042. // CPostCfgManager::HrFindGroupFromResourceOrItsDependents(
  3043. // ULONG idxResourceIn,
  3044. // CGroupHandle ** ppghOut
  3045. // )
  3046. //
  3047. //////////////////////////////////////////////////////////////////////////////
  3048. HRESULT
  3049. CPostCfgManager::HrFindGroupFromResourceOrItsDependents(
  3050. ULONG idxResourceIn,
  3051. CGroupHandle ** ppghOut
  3052. )
  3053. {
  3054. TraceFunc1( "idxResourceIn = %u", idxResourceIn );
  3055. HRESULT hr;
  3056. ULONG cDependents;
  3057. ULONG idxDependent;
  3058. BSTR bstrName; // don't free
  3059. BSTR bstrGroup = NULL;
  3060. HRESOURCE hResource;
  3061. HRESOURCE hResourceToClose = NULL;
  3062. HGROUP hGroup = NULL;
  3063. EDependencyFlags dfDependent;
  3064. CResourceEntry * presentry;
  3065. BSTR bstrNotification = NULL;
  3066. Assert( ppghOut != NULL );
  3067. presentry = m_rgpResources[ idxResourceIn ];
  3068. //
  3069. // See if we already have a cached version of the group handle.
  3070. //
  3071. hr = THR( presentry->GetGroupHandle( ppghOut) );
  3072. if ( FAILED( hr ) )
  3073. {
  3074. SSR_LOG_ERR(
  3075. TASKID_Major_Client_And_Server_Log
  3076. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_GetGroupHandle
  3077. , hr
  3078. , L"GetGroupHandle() failed."
  3079. );
  3080. STATUS_REPORT_REF_POSTCFG(
  3081. TASKID_Major_Configure_Resources
  3082. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_GetGroupHandle
  3083. , IDS_TASKID_MINOR_ERROR_GET_GROUP_HANDLE
  3084. , IDS_REF_MINOR_ERROR_GET_GROUP_HANDLE
  3085. , hr
  3086. );
  3087. goto Cleanup;
  3088. }
  3089. if ( hr == S_OK && *ppghOut != NULL )
  3090. {
  3091. goto Cleanup;
  3092. }
  3093. //
  3094. // Else, see if we can located an existing resource and group.
  3095. //
  3096. // don't wrap - this can fail with H_R_W32( ERROR_INVALID_DATA )
  3097. hr = presentry->GetHResource( &hResource );
  3098. if ( FAILED( hr ) )
  3099. {
  3100. Assert( hr == HRESULT_FROM_WIN32( ERROR_INVALID_DATA ) );
  3101. Assert( hResource == NULL );
  3102. // Just borrowing it's name.... don't free
  3103. hr = THR( presentry->GetName( &bstrName ) );
  3104. if ( hr == S_OK )
  3105. {
  3106. hResourceToClose = OpenClusterResource( m_hCluster, bstrName );
  3107. hResource = hResourceToClose;
  3108. }
  3109. }
  3110. else
  3111. {
  3112. // Just borrowing its name.... don't free.
  3113. // We may use the name later on if we need to report an error,
  3114. // so it's not a big deal if we fail to retrieve is here.
  3115. hr = THR( presentry->GetName( &bstrName ) );
  3116. }
  3117. if ( hResource != NULL )
  3118. {
  3119. CLUSTER_RESOURCE_STATE crs;
  3120. DWORD cbGroup = 200;
  3121. ReAllocGroupName:
  3122. bstrGroup = TraceSysAllocStringLen( NULL, cbGroup );
  3123. if ( bstrGroup == NULL )
  3124. {
  3125. hr = THR( E_OUTOFMEMORY );
  3126. SSR_LOG_ERR(
  3127. TASKID_Major_Client_And_Server_Log
  3128. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_OutOfMemory
  3129. , hr
  3130. , L"Out of Memory."
  3131. );
  3132. STATUS_REPORT_REF_POSTCFG(
  3133. TASKID_Major_Configure_Resources
  3134. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_OutOfMemory
  3135. , IDS_TASKID_MINOR_ERROR_OUT_OF_MEMORY
  3136. , IDS_REF_MINOR_ERROR_OUT_OF_MEMORY
  3137. , hr
  3138. );
  3139. goto Cleanup;
  3140. }
  3141. crs = GetClusterResourceState( hResource, NULL, NULL, bstrGroup, &cbGroup );
  3142. if ( crs != ClusterResourceStateUnknown )
  3143. {
  3144. hGroup = OpenClusterGroup( m_hCluster, bstrGroup );
  3145. if ( hGroup != NULL )
  3146. {
  3147. hr = THR( CGroupHandle::S_HrCreateInstance( ppghOut, hGroup ) );
  3148. if ( FAILED( hr ) )
  3149. {
  3150. SSR_LOG_ERR(
  3151. TASKID_Major_Client_And_Server_Log
  3152. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_Create_CGroupHandle
  3153. , hr
  3154. , L"Failed to create group handle instance."
  3155. );
  3156. STATUS_REPORT_REF_POSTCFG1(
  3157. TASKID_Major_Configure_Resources
  3158. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_Create_CGroupHandle
  3159. , IDS_TASKID_MINOR_ERROR_CREATE_GROUP_HANDLE
  3160. , IDS_REF_MINOR_ERROR_CREATE_GROUP_HANDLE
  3161. , hr
  3162. , bstrGroup
  3163. );
  3164. goto Cleanup;
  3165. }
  3166. hGroup = NULL; // gave ownership away above
  3167. goto Cleanup;
  3168. } // if: error creating the group
  3169. else
  3170. {
  3171. DWORD sc = TW32( GetLastError() );
  3172. hr = HRESULT_FROM_WIN32( sc );
  3173. SSR_LOG1(
  3174. TASKID_Major_Client_And_Server_Log
  3175. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_OpenClusterGroup
  3176. , hr
  3177. , L"[PC-Grouping] %1!ws!: OpenClusterGroup() failed. Aborting."
  3178. , bstrNotification
  3179. , bstrGroup
  3180. );
  3181. STATUS_REPORT_REF_POSTCFG1(
  3182. TASKID_Major_Configure_Resources
  3183. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_OpenClusterGroup
  3184. , IDS_TASKID_MINOR_ERROR_OPEN_GROUP
  3185. , IDS_REF_MINOR_ERROR_OPEN_GROUP
  3186. , hr
  3187. , bstrGroup
  3188. );
  3189. goto Cleanup;
  3190. } // else: error opening the group
  3191. } // if: resource state is known
  3192. else
  3193. {
  3194. DWORD sc = GetLastError();
  3195. switch ( sc )
  3196. {
  3197. case ERROR_MORE_DATA:
  3198. cbGroup += sizeof( WCHAR ); // add terminating NULL
  3199. TraceSysFreeString( bstrGroup );
  3200. goto ReAllocGroupName;
  3201. default:
  3202. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  3203. SSR_LOG1(
  3204. TASKID_Major_Client_And_Server_Log
  3205. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_GetClusterResourceState
  3206. , hr
  3207. , L"[PC-Grouping] %1!ws!: GetClusterResourceState() failed. Aborting."
  3208. , bstrNotification
  3209. , bstrName
  3210. );
  3211. STATUS_REPORT_REF_POSTCFG1(
  3212. TASKID_Major_Configure_Resources
  3213. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_GetClusterResourceState
  3214. , IDS_TASKID_MINOR_ERROR_RESOURCE_STATE
  3215. , IDS_REF_MINOR_ERROR_RESOURCE_STATE
  3216. , hr
  3217. , bstrName
  3218. );
  3219. goto Cleanup;
  3220. } // switch: status code
  3221. } // else: resource state is not known
  3222. } // if: resource is open
  3223. // else the resource might not exist... continue....
  3224. //
  3225. // Follow the depents list.
  3226. //
  3227. hr = THR( presentry->GetCountOfDependents( &cDependents ) );
  3228. if ( FAILED( hr ) )
  3229. {
  3230. SSR_LOG_ERR(
  3231. TASKID_Major_Client_And_Server_Log
  3232. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_GetCountOfDependents
  3233. , hr
  3234. , L"Failed to get the count of dependents."
  3235. );
  3236. STATUS_REPORT_REF_POSTCFG(
  3237. TASKID_Major_Configure_Resources
  3238. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_GetCountOfDependents
  3239. , IDS_TASKID_MINOR_ERROR_COUNT_OF_DEPENDENTS
  3240. , IDS_REF_MINOR_ERROR_COUNT_OF_DEPENDENTS
  3241. , hr
  3242. );
  3243. goto Cleanup;
  3244. }
  3245. for ( ; cDependents != 0 ; )
  3246. {
  3247. cDependents --;
  3248. hr = THR( presentry->GetDependent( cDependents, &idxDependent, &dfDependent ) );
  3249. if ( FAILED( hr ) )
  3250. {
  3251. SSR_LOG_ERR(
  3252. TASKID_Major_Client_And_Server_Log
  3253. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_GetDependent
  3254. , hr
  3255. , L"Failed to get a resource dependent."
  3256. );
  3257. STATUS_REPORT_MINOR_REF_POSTCFG(
  3258. TASKID_Major_Configure_Resources
  3259. , IDS_TASKID_MINOR_ERROR_GET_DEPENDENT
  3260. , IDS_REF_MINOR_ERROR_GET_DEPENDENT
  3261. , hr
  3262. );
  3263. goto Cleanup;
  3264. }
  3265. hr = STHR( HrFindGroupFromResourceOrItsDependents( idxDependent, ppghOut) );
  3266. if ( FAILED( hr ) )
  3267. {
  3268. goto Cleanup;
  3269. }
  3270. if ( hr == S_OK && *ppghOut != NULL )
  3271. {
  3272. goto Cleanup;
  3273. }
  3274. } // for: cDependents
  3275. //
  3276. // Failed to find an existing group.
  3277. //
  3278. hr = S_FALSE;
  3279. *ppghOut = NULL;
  3280. Cleanup:
  3281. if ( hResourceToClose != NULL )
  3282. {
  3283. CloseClusterResource( hResourceToClose );
  3284. }
  3285. if ( hGroup != NULL )
  3286. {
  3287. CloseClusterGroup( hGroup );
  3288. }
  3289. TraceSysFreeString( bstrGroup );
  3290. TraceSysFreeString( bstrNotification );
  3291. HRETURN( hr );
  3292. } //*** CPostCfgManager::HrFindGroupFromResourceOrItsDependents
  3293. //////////////////////////////////////////////////////////////////////////////
  3294. //
  3295. // HRESULT
  3296. // CPostCfgManager::HrCreateResourceAndDependents(
  3297. // ULONG idxResourceIn
  3298. // )
  3299. //
  3300. //////////////////////////////////////////////////////////////////////////////
  3301. HRESULT
  3302. CPostCfgManager::HrCreateResourceAndDependents(
  3303. ULONG idxResourceIn
  3304. )
  3305. {
  3306. TraceFunc1( "idxResourceIn = %u", idxResourceIn );
  3307. HRESULT hr;
  3308. BSTR bstrName; // don't free! - this is the resource's copy
  3309. BSTR bstrNameProp = NULL;
  3310. ULONG cDependents;
  3311. ULONG idxDependent;
  3312. HGROUP hGroup; // don't close! - this is the resource's copy
  3313. HRESOURCE hResource = NULL;
  3314. const CLSID * pclsidResType;
  3315. CGroupHandle * pgh;
  3316. EDependencyFlags dfDependent;
  3317. BSTR bstrNotification = NULL;
  3318. IClusCfgManagedResourceCfg * pccmrc = NULL;
  3319. CResourceEntry * presentry = m_rgpResources[ idxResourceIn ];
  3320. IUnknown * punkServices = NULL;
  3321. IPrivatePostCfgResource * ppcr = NULL;
  3322. IClusCfgResourceCreate * pccrc = NULL;
  3323. // Validate state
  3324. Assert( m_peccmr != NULL );
  3325. Assert( m_pccci != NULL );
  3326. //
  3327. // Create a service object for this resource.
  3328. //
  3329. hr = THR( CCreateServices::S_HrCreateInstance( &punkServices ) );
  3330. if ( FAILED( hr ) )
  3331. {
  3332. SSR_LOG_ERR(
  3333. TASKID_Major_Client_And_Server_Log
  3334. , TASKID_Minor_HrCreateResourceAndDependents_Create_CCreateServices
  3335. , hr
  3336. , L"[PC-Create] Failed to create services object. Aborting."
  3337. );
  3338. STATUS_REPORT_REF_POSTCFG(
  3339. TASKID_Minor_Creating_Resource
  3340. , TASKID_Minor_HrCreateResourceAndDependents_Create_CCreateServices
  3341. , IDS_TASKID_MINOR_ERROR_CREATE_SERVICE
  3342. , IDS_REF_MINOR_ERROR_CREATE_SERVICE
  3343. , hr
  3344. );
  3345. goto Cleanup;
  3346. }
  3347. hr = THR( punkServices->TypeSafeQI( IPrivatePostCfgResource, &ppcr ) );
  3348. if ( FAILED( hr ) )
  3349. {
  3350. SSR_LOG_ERR(
  3351. TASKID_Major_Client_And_Server_Log
  3352. , TASKID_Minor_HrCreateResourceAndDependents_Create_CCreateServices_QI
  3353. , hr
  3354. , L"Failed to QI for IPrivatePostCfgResource."
  3355. );
  3356. STATUS_REPORT_REF_POSTCFG(
  3357. TASKID_Minor_Creating_Resource
  3358. , TASKID_Minor_HrCreateResourceAndDependents_Create_CCreateServices_QI
  3359. , IDS_TASKID_MINOR_ERROR_CREATE_SERVICE
  3360. , IDS_REF_MINOR_ERROR_CREATE_SERVICE
  3361. , hr
  3362. );
  3363. goto Cleanup;
  3364. }
  3365. hr = THR( ppcr->SetEntry( presentry ) );
  3366. if ( FAILED( hr ) )
  3367. {
  3368. SSR_LOG_ERR(
  3369. TASKID_Major_Client_And_Server_Log
  3370. , TASKID_Minor_HrCreateResourceAndDependents_SetEntry
  3371. , hr
  3372. , L"Failed to set a private post configuration resource entry."
  3373. );
  3374. STATUS_REPORT_REF_POSTCFG(
  3375. TASKID_Minor_Creating_Resource
  3376. , TASKID_Minor_HrCreateResourceAndDependents_SetEntry
  3377. , IDS_TASKID_MINOR_ERROR_POST_SETENTRY
  3378. , IDS_REF_MINOR_ERROR_POST_SETENTRY
  3379. , hr
  3380. );
  3381. goto Cleanup;
  3382. }
  3383. //
  3384. // See if it was configured in a previous pass.
  3385. //
  3386. hr = STHR( presentry->IsConfigured() );
  3387. if ( FAILED( hr ) )
  3388. {
  3389. SSR_LOG_ERR(
  3390. TASKID_Major_Client_And_Server_Log
  3391. , TASKID_Minor_HrCreateResourceAndDependents_IsConfigured
  3392. , hr
  3393. , L"Failed to query if resource is configured."
  3394. );
  3395. STATUS_REPORT_REF_POSTCFG(
  3396. TASKID_Minor_Creating_Resource
  3397. , TASKID_Minor_HrCreateResourceAndDependents_IsConfigured
  3398. , IDS_TASKID_MINOR_ERROR_ISCONFIGURED
  3399. , IDS_REF_MINOR_ERROR_ISCONFIGURED
  3400. , hr
  3401. );
  3402. goto Cleanup;
  3403. }
  3404. if ( hr == S_FALSE )
  3405. {
  3406. //
  3407. // Make sure that Create() is not called again because of recursion.
  3408. //
  3409. hr = THR( presentry->SetConfigured( TRUE ) );
  3410. if ( FAILED( hr ) )
  3411. {
  3412. SSR_LOG_ERR(
  3413. TASKID_Major_Client_And_Server_Log
  3414. , TASKID_Minor_HrCreateResourceAndDependents_SetConfigured
  3415. , hr
  3416. , L"Failed to set resource as configured."
  3417. );
  3418. STATUS_REPORT_REF_POSTCFG(
  3419. TASKID_Minor_Creating_Resource
  3420. , TASKID_Minor_HrCreateResourceAndDependents_SetConfigured
  3421. , IDS_TASKID_MINOR_ERROR_SETCONFIGURED
  3422. , IDS_REF_MINOR_ERROR_SETCONFIGURED
  3423. , hr
  3424. );
  3425. goto Cleanup;
  3426. }
  3427. //
  3428. // Grab some useful information: name, group handle, ...
  3429. //
  3430. hr = THR( presentry->GetName( &bstrName ) );
  3431. if ( FAILED( hr ) )
  3432. {
  3433. SSR_LOG_ERR(
  3434. TASKID_Major_Client_And_Server_Log
  3435. , TASKID_Minor_HrCreateResourceAndDependents_GetName
  3436. , hr
  3437. , L"Failed to get resource name."
  3438. );
  3439. STATUS_REPORT_REF_POSTCFG(
  3440. TASKID_Minor_Creating_Resource
  3441. , TASKID_Minor_HrCreateResourceAndDependents_GetName
  3442. , IDS_TASKID_MINOR_ERROR_GET_RESOURCE_NAME
  3443. , IDS_REF_MINOR_ERROR_GET_RESOURCE_NAME
  3444. , hr
  3445. );
  3446. goto Cleanup;
  3447. }
  3448. hr = THR( presentry->GetGroupHandle( &pgh) );
  3449. if ( FAILED( hr ) )
  3450. {
  3451. SSR_LOG_ERR(
  3452. TASKID_Major_Client_And_Server_Log
  3453. , TASKID_Minor_HrCreateResourceAndDependents_GetGroupHandle
  3454. , hr
  3455. , L"Failed to get a group handle pointer."
  3456. );
  3457. STATUS_REPORT_REF_POSTCFG(
  3458. TASKID_Minor_Creating_Resource
  3459. , TASKID_Minor_HrCreateResourceAndDependents_GetGroupHandle
  3460. , IDS_TASKID_MINOR_ERROR_GET_GROUP_HANDLE_PTR
  3461. , IDS_REF_MINOR_ERROR_GET_GROUP_HANDLE_PTR
  3462. , hr
  3463. );
  3464. goto Cleanup;
  3465. }
  3466. hr = THR( pgh->GetHandle( &hGroup ) );
  3467. pgh->Release(); // release promptly
  3468. if ( FAILED( hr ) )
  3469. {
  3470. SSR_LOG_ERR(
  3471. TASKID_Major_Client_And_Server_Log
  3472. , TASKID_Minor_HrCreateResourceAndDependents_GetHandle
  3473. , hr
  3474. , L"Failed to get a group handle."
  3475. );
  3476. STATUS_REPORT_REF_POSTCFG(
  3477. TASKID_Minor_Creating_Resource
  3478. , TASKID_Minor_HrCreateResourceAndDependents_GetHandle
  3479. , IDS_TASKID_MINOR_ERROR_GET_GROUP_HANDLE
  3480. , IDS_REF_MINOR_ERROR_GET_GROUP_HANDLE
  3481. , hr
  3482. );
  3483. goto Cleanup;
  3484. }
  3485. //
  3486. // Some resource that we pre-create don't have an associated managed resource.
  3487. // Skip "creating" them but do create their dependents. Note that "special"
  3488. // resources are create below in the else statement.
  3489. //
  3490. // Don't wrap - this can fail with Win32 ERROR_INVALID_DATA if the pointer is invalid.
  3491. hr = presentry->GetAssociatedResource( &pccmrc );
  3492. if ( FAILED( hr ) && hr != HRESULT_FROM_WIN32( ERROR_INVALID_DATA ) )
  3493. {
  3494. THR( hr );
  3495. SSR_LOG_ERR(
  3496. TASKID_Major_Client_And_Server_Log
  3497. , TASKID_Minor_HrCreateResourceAndDependents_GetAssociatedResource
  3498. , hr
  3499. , L"Failed to get an associated resource."
  3500. );
  3501. STATUS_REPORT_REF_POSTCFG(
  3502. TASKID_Minor_Creating_Resource
  3503. , TASKID_Minor_HrCreateResourceAndDependents_GetAssociatedResource
  3504. , IDS_TASKID_MINOR_ERROR_GET_ASSOC_RES
  3505. , IDS_REF_MINOR_ERROR_GET_ASSOC_RES
  3506. , hr
  3507. );
  3508. goto Cleanup;
  3509. }
  3510. if ( SUCCEEDED( hr ) )
  3511. {
  3512. // Don't wrap - this can fail with E_NOTIMPL.
  3513. hr = pccmrc->Create( punkServices );
  3514. if ( FAILED( hr ) )
  3515. {
  3516. if ( hr == E_NOTIMPL )
  3517. {
  3518. hr = S_OK; // ignore the error.
  3519. } // if: E_NOTIMPL
  3520. else
  3521. {
  3522. SSR_LOG1(
  3523. TASKID_Major_Client_And_Server_Log
  3524. , TASKID_Minor_HrCreateResourceAndDependents_Create_Failed
  3525. , hr
  3526. , L"[PC-Create] %1!ws!: Create() failed. Its dependents may not be created. Skipping."
  3527. , bstrNotification
  3528. , bstrName
  3529. );
  3530. STATUS_REPORT_REF_POSTCFG1(
  3531. TASKID_Minor_Creating_Resource
  3532. , TASKID_Minor_HrCreateResourceAndDependents_Create_Failed
  3533. , IDS_TASKID_MINOR_ERROR_CREATE_FAILED
  3534. , IDS_REF_MINOR_ERROR_CREATE_FAILED
  3535. , hr
  3536. , bstrName
  3537. );
  3538. if ( hr == E_ABORT )
  3539. goto Cleanup;
  3540. // ignore failure
  3541. } // else: other failure
  3542. } // if: failure
  3543. if ( SUCCEEDED( hr ) )
  3544. {
  3545. LPCWSTR pcszResType; // don't free.
  3546. hr = THR( presentry->GetTypePtr( &pclsidResType ) );
  3547. if ( FAILED( hr ) )
  3548. {
  3549. SSR_LOG_ERR(
  3550. TASKID_Major_Client_And_Server_Log
  3551. , TASKID_Minor_HrCreateResourceAndDependents_GetTypePtr
  3552. , hr
  3553. , L"Failed to get resource type pointer."
  3554. );
  3555. STATUS_REPORT_REF_POSTCFG(
  3556. TASKID_Minor_Creating_Resource
  3557. , TASKID_Minor_HrCreateResourceAndDependents_GetTypePtr
  3558. , IDS_TASKID_MINOR_ERROR_GET_RESTYPE_PTR
  3559. , IDS_REF_MINOR_ERROR_GET_RESTYPE_PTR
  3560. , hr
  3561. );
  3562. goto Cleanup;
  3563. }
  3564. pcszResType = PcszLookupTypeNameByGUID( *pclsidResType );
  3565. if ( pcszResType == NULL )
  3566. {
  3567. hr = HRESULT_FROM_WIN32 ( ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND );
  3568. SSR_LOG1(
  3569. TASKID_Major_Client_And_Server_Log
  3570. , TASKID_Minor_HrCreateResourceAndDependents_PcszLookupTypeNameByGUID
  3571. , hr
  3572. , L"[PC-Create] %1!ws!: Resource cannot be created because the resource type is not registered. Its dependents may not be created. Skipping."
  3573. , bstrNotification
  3574. , bstrName
  3575. );
  3576. STATUS_REPORT_REF_POSTCFG1(
  3577. TASKID_Minor_Creating_Resource
  3578. , TASKID_Minor_HrCreateResourceAndDependents_PcszLookupTypeNameByGUID
  3579. , IDS_TASKID_MINOR_RESTYPE_NOT_REGISTERED
  3580. , IDS_REF_MINOR_RESTYPE_NOT_REGISTERED
  3581. , hr
  3582. , bstrName
  3583. );
  3584. }
  3585. else
  3586. {
  3587. hr = THR( HrCreateResourceInstance( idxResourceIn, hGroup, pcszResType, &hResource ) );
  3588. if ( FAILED( hr ) )
  3589. goto Cleanup;
  3590. }
  3591. } // if: success
  3592. } // if: interface
  3593. else
  3594. {
  3595. //
  3596. // See if it is one of the "special" types that we can generate on the fly.
  3597. //
  3598. const CLSID * pclsidType;
  3599. hr = THR( presentry->GetTypePtr( &pclsidType ) );
  3600. if ( FAILED( hr ) )
  3601. {
  3602. SSR_LOG_ERR(
  3603. TASKID_Major_Client_And_Server_Log
  3604. , TASKID_Minor_HrCreateResourceAndDependents_InvalidData_GetTypePtr
  3605. , hr
  3606. , L"Failed to get resource type pointer."
  3607. );
  3608. STATUS_REPORT_REF_POSTCFG(
  3609. TASKID_Minor_Creating_Resource
  3610. , TASKID_Minor_HrCreateResourceAndDependents_InvalidData_GetTypePtr
  3611. , IDS_TASKID_MINOR_ERROR_GET_RESTYPE_PTR
  3612. , IDS_REF_MINOR_ERROR_GET_RESTYPE_PTR
  3613. , hr
  3614. );
  3615. goto Cleanup;
  3616. }
  3617. if ( *pclsidType == RESTYPE_NetworkName )
  3618. {
  3619. //
  3620. // Create a new network name resource.
  3621. //
  3622. hr = THR( punkServices->TypeSafeQI( IClusCfgResourceCreate, &pccrc ) );
  3623. if ( FAILED( hr ) )
  3624. {
  3625. SSR_LOG_ERR(
  3626. TASKID_Major_Client_And_Server_Log
  3627. , TASKID_Minor_HrCreateResourceAndDependents_NetworkName_QI_pccrc
  3628. , hr
  3629. , L"Failed to QI for IClusCfgResourceCreate."
  3630. );
  3631. STATUS_REPORT_REF_POSTCFG(
  3632. TASKID_Minor_Creating_Resource
  3633. , TASKID_Minor_HrCreateResourceAndDependents_NetworkName_QI_pccrc
  3634. , IDS_TASKID_MINOR_ERROR_RESOURCE_CREATE
  3635. , IDS_REF_MINOR_ERROR_RESOURCE_CREATE
  3636. , hr
  3637. );
  3638. goto Cleanup;
  3639. }
  3640. //
  3641. // Replace the spaces in the resource name with underscores (spaces can't
  3642. // be used in a computer name).
  3643. //
  3644. bstrNameProp = TraceSysAllocString( bstrName );
  3645. if ( bstrNameProp == NULL )
  3646. {
  3647. hr = THR( E_OUTOFMEMORY );
  3648. SSR_LOG_ERR(
  3649. TASKID_Minor_Creating_Resource
  3650. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_OutOfMemory
  3651. , hr
  3652. , L"Out of Memory."
  3653. );
  3654. STATUS_REPORT_REF_POSTCFG(
  3655. TASKID_Minor_Creating_Resource
  3656. , TASKID_Minor_HrFindGroupFromResourceOrItsDependents_OutOfMemory
  3657. , IDS_TASKID_MINOR_ERROR_OUT_OF_MEMORY
  3658. , IDS_REF_MINOR_ERROR_OUT_OF_MEMORY
  3659. , hr
  3660. );
  3661. goto Cleanup;
  3662. }
  3663. hr = THR( HrReplaceTokens( bstrNameProp, L" ", L'_', NULL ) );
  3664. if ( FAILED( hr ) )
  3665. {
  3666. SSR_LOG_ERR(
  3667. TASKID_Minor_Creating_Resource
  3668. ,TASKID_Minor_HrFindGroupFromResourceOrItsDependents_ReplaceTokens
  3669. ,hr
  3670. , L"HrReplaceTokens failed. Using resource name for private Name prop."
  3671. );
  3672. }
  3673. hr = THR( pccrc->SetPropertyString( L"Name", bstrNameProp ) );
  3674. if ( FAILED( hr ) )
  3675. {
  3676. SSR_LOG_ERR(
  3677. TASKID_Major_Client_And_Server_Log
  3678. , TASKID_Minor_HrCreateResourceAndDependents_NetworkName_SetPropertyString
  3679. , hr
  3680. , L"Failed to set name property of resurce."
  3681. );
  3682. STATUS_REPORT_REF_POSTCFG1(
  3683. TASKID_Minor_Creating_Resource
  3684. , TASKID_Minor_HrCreateResourceAndDependents_NetworkName_SetPropertyString
  3685. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_NAME
  3686. , IDS_REF_MINOR_ERROR_SET_RESOURCE_NAME
  3687. , hr
  3688. , bstrName
  3689. );
  3690. goto Cleanup;
  3691. }
  3692. hr = THR( HrCreateResourceInstance( idxResourceIn, hGroup, L"Network Name", &hResource ) );
  3693. if ( FAILED( hr ) )
  3694. {
  3695. goto Cleanup;
  3696. }
  3697. }
  3698. else if ( *pclsidType == RESTYPE_IPAddress )
  3699. {
  3700. //
  3701. // Create a new IP address resource.
  3702. //
  3703. hr = THR( punkServices->TypeSafeQI( IClusCfgResourceCreate, &pccrc ) );
  3704. if ( FAILED( hr ) )
  3705. {
  3706. SSR_LOG_ERR(
  3707. TASKID_Major_Client_And_Server_Log
  3708. , TASKID_Minor_HrCreateResourceAndDependents_IPAddress_QI_pccrc
  3709. , hr
  3710. , L"Failed to QI for IClusCfgResourceCreate."
  3711. );
  3712. STATUS_REPORT_REF_POSTCFG(
  3713. TASKID_Minor_Creating_Resource
  3714. , TASKID_Minor_HrCreateResourceAndDependents_IPAddress_QI_pccrc
  3715. , IDS_TASKID_MINOR_ERROR_RESOURCE_CREATE
  3716. , IDS_REF_MINOR_ERROR_RESOURCE_CREATE
  3717. , hr
  3718. );
  3719. goto Cleanup;
  3720. }
  3721. //
  3722. // TODO: gpease 21-JUN-2000
  3723. // Since we do not have a way to generate an appropriate IP address,
  3724. // we don't set any properties. This will cause it to fail to come
  3725. // online.
  3726. //
  3727. hr = THR( HrCreateResourceInstance( idxResourceIn, hGroup, L"IP Address", &hResource ) );
  3728. if ( FAILED( hr ) )
  3729. {
  3730. goto Cleanup;
  3731. }
  3732. }
  3733. else
  3734. {
  3735. //
  3736. // else... the resource is one of the pre-created resources that BaseCluster
  3737. // created. Log and continue creating its dependents.
  3738. //
  3739. hr = S_OK;
  3740. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  3741. TASKID_Minor_HrCreateResourceAndDependents_NothingNew,
  3742. hr,
  3743. L"[PC-Create] %1!ws!: Nothing new to create. Configuring dependents.",
  3744. bstrNotification,
  3745. bstrName
  3746. );
  3747. }
  3748. } // else: no interface
  3749. } // if: not created
  3750. else
  3751. {
  3752. hr = THR( presentry->GetName( &bstrName ) );
  3753. if ( FAILED( hr ) )
  3754. {
  3755. SSR_LOG_ERR(
  3756. TASKID_Major_Client_And_Server_Log
  3757. , TASKID_Minor_HrCreateResourceAndDependents_GetName
  3758. , hr
  3759. , L"Failed to get resource name."
  3760. );
  3761. STATUS_REPORT_REF_POSTCFG(
  3762. TASKID_Minor_Creating_Resource
  3763. , TASKID_Minor_HrCreateResourceAndDependents_GetName
  3764. , IDS_TASKID_MINOR_ERROR_GET_RESOURCE_NAME
  3765. , IDS_REF_MINOR_ERROR_GET_RESOURCE_NAME
  3766. , hr
  3767. );
  3768. goto Cleanup;
  3769. }
  3770. hr = THR( presentry->GetHResource( &hResource ) );
  3771. if ( FAILED( hr ) )
  3772. {
  3773. SSR_LOG_ERR(
  3774. TASKID_Major_Client_And_Server_Log
  3775. , TASKID_Minor_HrCreateResourceAndDependents_GetHandle
  3776. , hr
  3777. , L"Failed to get resource handle."
  3778. );
  3779. STATUS_REPORT_REF_POSTCFG(
  3780. TASKID_Minor_Creating_Resource
  3781. , TASKID_Minor_HrCreateResourceAndDependents_GetHandle
  3782. , IDS_TASKID_MINOR_ERROR_GET_RESOURCE_HANDLE
  3783. , IDS_REF_MINOR_ERROR_GET_RESOURCE_HANDLE
  3784. , hr
  3785. );
  3786. goto Cleanup;
  3787. }
  3788. } // else: already created
  3789. //
  3790. // Now that we created the resource instance, we need to create its dependents.
  3791. //
  3792. hr = THR( presentry->GetCountOfDependents( &cDependents ) );
  3793. if ( FAILED( hr ) )
  3794. {
  3795. SSR_LOG_ERR(
  3796. TASKID_Major_Client_And_Server_Log
  3797. , TASKID_Minor_HrCreateResourceAndDependents_Dependents_GetCountOfDependents
  3798. , hr
  3799. , L"Failed to get the count of dependents."
  3800. );
  3801. STATUS_REPORT_REF_POSTCFG(
  3802. TASKID_Minor_Creating_Resource
  3803. , TASKID_Minor_HrCreateResourceAndDependents_Dependents_GetCountOfDependents
  3804. , IDS_TASKID_MINOR_ERROR_COUNT_OF_DEPENDENTS
  3805. , IDS_REF_MINOR_ERROR_COUNT_OF_DEPENDENTS
  3806. , hr
  3807. );
  3808. goto Cleanup;
  3809. }
  3810. for( ; cDependents != 0; )
  3811. {
  3812. DWORD dw;
  3813. BSTR bstrDependent;
  3814. HRESOURCE hResourceDependent;
  3815. CResourceEntry * presentryDependent;
  3816. cDependents --;
  3817. hr = THR( presentry->GetDependent( cDependents, &idxDependent, &dfDependent ) );
  3818. if ( FAILED( hr ) )
  3819. {
  3820. SSR_LOG_ERR(
  3821. TASKID_Major_Client_And_Server_Log
  3822. , TASKID_Minor_HrCreateResourceAndDependents_Dependents_GetDependent
  3823. , hr
  3824. , L"Failed to get a resource dependent."
  3825. );
  3826. STATUS_REPORT_MINOR_REF_POSTCFG(
  3827. TASKID_Minor_Creating_Resource
  3828. , IDS_TASKID_MINOR_ERROR_GET_DEPENDENT
  3829. , IDS_REF_MINOR_ERROR_GET_DEPENDENT
  3830. , hr
  3831. );
  3832. continue;
  3833. }
  3834. hr = THR( HrCreateResourceAndDependents( idxDependent ) );
  3835. if ( FAILED( hr ) )
  3836. {
  3837. continue;
  3838. }
  3839. //
  3840. // Add the dependencies on the resource.
  3841. //
  3842. presentryDependent = m_rgpResources[ idxDependent ];
  3843. hr = THR( presentryDependent->GetName( &bstrDependent ) );
  3844. if ( FAILED( hr ) )
  3845. {
  3846. SSR_LOG_ERR(
  3847. TASKID_Major_Client_And_Server_Log
  3848. , TASKID_Minor_HrCreateResourceAndDependents_Dependents_GetName
  3849. , hr
  3850. , L"Failed to get dependent resource name."
  3851. );
  3852. STATUS_REPORT_MINOR_REF_POSTCFG(
  3853. TASKID_Minor_Creating_Resource
  3854. , IDS_TASKID_MINOR_ERROR_GET_RESOURCE_NAME
  3855. , IDS_REF_MINOR_ERROR_GET_RESOURCE_NAME
  3856. , hr
  3857. );
  3858. continue;
  3859. }
  3860. hr = THR( presentryDependent->GetHResource( &hResourceDependent ) );
  3861. if ( FAILED( hr ) )
  3862. {
  3863. SSR_LOG_ERR(
  3864. TASKID_Major_Client_And_Server_Log
  3865. , TASKID_Minor_HrCreateResourceAndDependents_Dependents_GetHResource
  3866. , hr
  3867. , L"Failed to get dependent resource handle."
  3868. );
  3869. STATUS_REPORT_MINOR_REF_POSTCFG(
  3870. TASKID_Minor_Creating_Resource
  3871. , IDS_TASKID_MINOR_ERROR_DEP_RESOURCE_HANDLE
  3872. , IDS_REF_MINOR_ERROR_DEP_RESOURCE_HANDLE
  3873. , hr
  3874. );
  3875. continue;
  3876. }
  3877. // don't wrap - this might fail with ERROR_DEPENDENCY_ALREADY_EXISTS
  3878. dw = AddClusterResourceDependency( hResourceDependent, hResource );
  3879. if ( ( dw != ERROR_SUCCESS ) && ( dw != ERROR_DEPENDENCY_ALREADY_EXISTS ) )
  3880. {
  3881. hr = HRESULT_FROM_WIN32( TW32( dw ) );
  3882. SSR_LOG2(
  3883. TASKID_Major_Client_And_Server_Log
  3884. , TASKID_Minor_HrCreateResourceAndDependents_Dependents_AddClusterResourceDependency
  3885. , hr
  3886. , L"[PC-Create] %1!ws!: Could not set dependency on %2!ws!."
  3887. , bstrNotification
  3888. , bstrDependent
  3889. , bstrName
  3890. );
  3891. STATUS_REPORT_MINOR_REF_POSTCFG2(
  3892. TASKID_Minor_Creating_Resource
  3893. , IDS_TASKID_MINOR_ERROR_ADD_RESOURCE_DEPENDENCY
  3894. , IDS_REF_MINOR_ERROR_ADD_RESOURCE_DEPENDENCY
  3895. , hr
  3896. , bstrDependent
  3897. , bstrName
  3898. );
  3899. }
  3900. else
  3901. {
  3902. hr = S_OK;
  3903. SSR_LOG2( TASKID_Major_Client_And_Server_Log,
  3904. TASKID_Minor_HrCreateResourceAndDependents_Dependents_Succeeded,
  3905. hr,
  3906. L"[PC-Create] %1!ws!: Successfully set dependency set on %2!ws!.",
  3907. bstrNotification,
  3908. bstrDependent,
  3909. bstrName
  3910. );
  3911. }
  3912. } // for: cDependents
  3913. hr = S_OK;
  3914. Cleanup:
  3915. TraceSysFreeString( bstrNotification );
  3916. TraceSysFreeString( bstrNameProp );
  3917. if ( pccmrc != NULL )
  3918. {
  3919. pccmrc->Release();
  3920. }
  3921. if ( punkServices != NULL )
  3922. {
  3923. punkServices->Release();
  3924. }
  3925. if ( ppcr != NULL )
  3926. {
  3927. ppcr->Release();
  3928. }
  3929. if ( pccrc != NULL )
  3930. {
  3931. pccrc->Release();
  3932. }
  3933. HRETURN( hr );
  3934. } //*** CPostCfgManager::HrCreateResourceAndDependents
  3935. //////////////////////////////////////////////////////////////////////////////
  3936. //
  3937. // HRESULT
  3938. // CPostCfgManager::HrPostCreateResourceAndDependents(
  3939. // ULONG idxResourceIn
  3940. // )
  3941. //
  3942. //////////////////////////////////////////////////////////////////////////////
  3943. HRESULT
  3944. CPostCfgManager::HrPostCreateResourceAndDependents(
  3945. ULONG idxResourceIn
  3946. )
  3947. {
  3948. TraceFunc1( "idxResourceIn = %u", idxResourceIn );
  3949. Assert( m_ecmCommitChangesMode != cmUNKNOWN );
  3950. DWORD sc;
  3951. HRESULT hr;
  3952. BSTR bstrName; // don't free
  3953. ULONG cDependents;
  3954. ULONG idxDependent;
  3955. HRESOURCE hResource;
  3956. EDependencyFlags dfDependent;
  3957. BSTR bstrNotification = NULL;
  3958. BSTR bstrLocalQuorumNotification = NULL;
  3959. IClusCfgManagedResourceCfg * pccmrc = NULL;
  3960. CResourceEntry * presentry = m_rgpResources[ idxResourceIn ];
  3961. IUnknown * punkServices = NULL;
  3962. IPrivatePostCfgResource * ppcr = NULL;
  3963. // Validate state
  3964. Assert( m_peccmr != NULL );
  3965. Assert( m_pccci != NULL );
  3966. hr = STHR( presentry->IsConfigured() );
  3967. if ( FAILED( hr ) )
  3968. {
  3969. SSR_LOG_ERR(
  3970. TASKID_Major_Client_And_Server_Log
  3971. , TASKID_Minor_HrPostCreateResourceAndDependents_IsConfigured
  3972. , hr
  3973. , L"Failed to query if resource is configured."
  3974. );
  3975. STATUS_REPORT_REF_POSTCFG(
  3976. TASKID_Minor_Starting_Resources
  3977. , TASKID_Minor_HrPostCreateResourceAndDependents_IsConfigured
  3978. , IDS_TASKID_MINOR_ERROR_ISCONFIGURED
  3979. , IDS_REF_MINOR_ERROR_ISCONFIGURED
  3980. , hr
  3981. );
  3982. goto Cleanup;
  3983. }
  3984. if ( hr == S_FALSE )
  3985. {
  3986. //
  3987. // Make sure that PostCreate() is not called again because of recursion.
  3988. //
  3989. hr = THR( presentry->SetConfigured( TRUE ) );
  3990. if ( FAILED( hr ) )
  3991. {
  3992. SSR_LOG_ERR(
  3993. TASKID_Major_Client_And_Server_Log
  3994. , TASKID_Minor_HrPostCreateResourceAndDependents_SetConfigured
  3995. , hr
  3996. , L"Failed to set resource as configured."
  3997. );
  3998. STATUS_REPORT_REF_POSTCFG(
  3999. TASKID_Minor_Starting_Resources
  4000. , TASKID_Minor_HrPostCreateResourceAndDependents_SetConfigured
  4001. , IDS_TASKID_MINOR_ERROR_SETCONFIGURED
  4002. , IDS_REF_MINOR_ERROR_SETCONFIGURED
  4003. , hr
  4004. );
  4005. goto Cleanup;
  4006. }
  4007. //
  4008. // Grab the name of the resource for logging.
  4009. //
  4010. hr = THR( presentry->GetName( &bstrName ) );
  4011. if ( FAILED( hr ) )
  4012. {
  4013. SSR_LOG_ERR(
  4014. TASKID_Major_Client_And_Server_Log
  4015. , TASKID_Minor_HrPostCreateResourceAndDependents_GetName
  4016. , hr
  4017. , L"Failed to get resource name."
  4018. );
  4019. STATUS_REPORT_REF_POSTCFG(
  4020. TASKID_Minor_Starting_Resources
  4021. , TASKID_Minor_HrPostCreateResourceAndDependents_GetName
  4022. , IDS_TASKID_MINOR_ERROR_GET_RESOURCE_NAME
  4023. , IDS_REF_MINOR_ERROR_GET_RESOURCE_NAME
  4024. , hr
  4025. );
  4026. goto Cleanup;
  4027. }
  4028. //
  4029. // Bring the resource online.
  4030. //
  4031. hr = presentry->GetHResource( &hResource );
  4032. if ( SUCCEEDED( hr ) )
  4033. {
  4034. // Don't wrap - can return ERROR_IO_PENDING.
  4035. sc = OnlineClusterResource( hResource );
  4036. switch ( sc )
  4037. {
  4038. case ERROR_SUCCESS:
  4039. hr = S_OK;
  4040. SSR_LOG1(
  4041. TASKID_Major_Client_And_Server_Log
  4042. , TASKID_Minor_HrPostCreateResourceAndDependents_OpenClusterResource
  4043. , hr
  4044. , L"[PC-PostCreate] %1!ws!: Resource brought online successfully."
  4045. , bstrNotification
  4046. , bstrName
  4047. );
  4048. STATUS_REPORT_MINOR_POSTCFG1(
  4049. TASKID_Minor_Starting_Resources
  4050. , IDS_TASKID_MINOR_RESOURCE_ONLINE
  4051. , hr
  4052. , bstrName
  4053. );
  4054. break;
  4055. case ERROR_IO_PENDING:
  4056. {
  4057. CLUSTER_RESOURCE_STATE crs = ClusterResourceOnlinePending;
  4058. HRESULT hr2 = S_OK;
  4059. hr = HRESULT_FROM_WIN32( sc );
  4060. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  4061. TASKID_Minor_HrPostCreateResourceAndDependents_OpenClusterResourcePending,
  4062. hr2,
  4063. L"[PC-PostCreate] %1!ws!: Online pending...",
  4064. bstrNotification,
  4065. bstrName
  4066. );
  4067. for( ; crs == ClusterResourceOnlinePending ; )
  4068. {
  4069. crs = GetClusterResourceState( hResource,
  4070. NULL,
  4071. NULL,
  4072. NULL,
  4073. NULL
  4074. );
  4075. switch ( crs )
  4076. {
  4077. case ClusterResourceOnline:
  4078. hr = S_OK;
  4079. SSR_LOG1(
  4080. TASKID_Major_Client_And_Server_Log
  4081. , TASKID_Minor_HrPostCreateResourceAndDependents_OpenClusterResource
  4082. , hr
  4083. , L"[PC-PostCreate] %1!ws!: Resource brought online successfully."
  4084. , bstrNotification
  4085. , bstrName
  4086. );
  4087. STATUS_REPORT_MINOR_POSTCFG1(
  4088. TASKID_Minor_Starting_Resources
  4089. , IDS_TASKID_MINOR_RESOURCE_ONLINE
  4090. , hr
  4091. , bstrName
  4092. );
  4093. break;
  4094. case ClusterResourceInitializing:
  4095. crs = ClusterResourceOnlinePending;
  4096. // fall thru
  4097. case ClusterResourceOnlinePending:
  4098. Sleep( 500 ); // sleep a 1/2 second
  4099. break;
  4100. case ClusterResourceStateUnknown:
  4101. sc = GetLastError();
  4102. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  4103. SSR_LOG1(
  4104. TASKID_Major_Client_And_Server_Log
  4105. , TASKID_Minor_HrPostCreateResourceAndDependents_ClusterResourceStateUnknown
  4106. , hr
  4107. , L"[PC-PostCreate] %1!ws!: Resource failed to come online. Dependent resources might fail too."
  4108. , bstrNotification
  4109. , bstrName
  4110. );
  4111. STATUS_REPORT_MINOR_REF_POSTCFG1(
  4112. TASKID_Minor_Starting_Resources
  4113. , IDS_TASKID_MINOR_RESOURCE_FAIL_ONLINE
  4114. , IDS_REF_MINOR_RESOURCE_FAIL_ONLINE
  4115. , hr
  4116. , bstrName
  4117. );
  4118. break;
  4119. case ClusterResourceOfflinePending:
  4120. case ClusterResourceOffline:
  4121. hr = THR( E_FAIL );
  4122. SSR_LOG1(
  4123. TASKID_Major_Client_And_Server_Log
  4124. , TASKID_Minor_HrPostCreateResourceAndDependents_ClusterResourceOffline
  4125. , hr
  4126. , L"[PC-PostCreate] %1!ws!: Resource went offline. Dependent resources might fail too."
  4127. , bstrNotification
  4128. , bstrName
  4129. );
  4130. STATUS_REPORT_MINOR_REF_POSTCFG1(
  4131. TASKID_Minor_Starting_Resources
  4132. , IDS_TASKID_MINOR_RESOURCE_WENT_OFFLINE
  4133. , IDS_REF_MINOR_RESOURCE_WENT_OFFLINE
  4134. , hr
  4135. , bstrName
  4136. );
  4137. break;
  4138. case ClusterResourceFailed:
  4139. hr = E_FAIL;
  4140. SSR_LOG1(
  4141. TASKID_Major_Client_And_Server_Log
  4142. , TASKID_Minor_HrPostCreateResourceAndDependents_ClusterResourceFailed
  4143. , hr
  4144. , L"[PC-PostCreate] %1!ws!: Resource failed. Check Event Log. Dependent resources might fail too."
  4145. , bstrNotification
  4146. , bstrName
  4147. );
  4148. STATUS_REPORT_MINOR_REF_POSTCFG1(
  4149. TASKID_Minor_Starting_Resources
  4150. , IDS_TASKID_MINOR_RESOURCE_FAILED
  4151. , IDS_REF_MINOR_RESOURCE_FAILED
  4152. , hr
  4153. , bstrName
  4154. );
  4155. break;
  4156. } // switch: crs
  4157. } // for: crs
  4158. }
  4159. break;
  4160. default:
  4161. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  4162. SSR_LOG1(
  4163. TASKID_Major_Client_And_Server_Log
  4164. , TASKID_Minor_HrPostCreateResourceAndDependents_OnlineClusterResource_Failed
  4165. , hr
  4166. , L"[PC-PostCreate] %1!ws!: Resource failed to come online. Dependent resources might fail too."
  4167. , bstrNotification
  4168. , bstrName
  4169. );
  4170. STATUS_REPORT_MINOR_REF_POSTCFG1(
  4171. TASKID_Minor_Starting_Resources
  4172. , IDS_TASKID_MINOR_RESOURCE_FAIL_ONLINE
  4173. , IDS_REF_MINOR_RESOURCE_FAIL_ONLINE
  4174. , hr
  4175. , bstrName
  4176. );
  4177. break;
  4178. } // switch: sc
  4179. } // if: hResource
  4180. //
  4181. // Set it to the quorum resource if marked so.
  4182. //
  4183. if ( SUCCEEDED( hr ) && idxResourceIn == m_idxQuorumResource && m_fIsQuorumChanged )
  4184. {
  4185. DWORD cchResName = 0;
  4186. DWORD cchDevName = 0;
  4187. DWORD dwMaxQuorumLogSize = 0;
  4188. //
  4189. // First, get the old max quorum log size. If we fail use the default log size.
  4190. //
  4191. sc = TW32( GetClusterQuorumResource(
  4192. m_hCluster,
  4193. NULL,
  4194. &cchResName,
  4195. NULL,
  4196. &cchDevName,
  4197. &dwMaxQuorumLogSize
  4198. ) );
  4199. if ( sc != ERROR_SUCCESS )
  4200. {
  4201. SSR_LOG1(
  4202. TASKID_Major_Client_And_Server_Log
  4203. , TASKID_HrPostCreateResourceAndDependents_GetClusterQuorumResource_Failed
  4204. , sc
  4205. , L"[PC-PostCreate] Failed to retrieve the current max log size. Defaulting to %1!d!."
  4206. , bstrNotification
  4207. , CLUSTER_QUORUM_DEFAULT_MAX_LOG_SIZE
  4208. );
  4209. STATUS_REPORT_MINOR_REF_POSTCFG(
  4210. TASKID_Minor_Starting_Resources
  4211. , IDS_TASKID_MINOR_ERROR_GET_QUORUM_LOG_SIZE
  4212. , IDS_REF_MINOR_ERROR_GET_QUORUM_LOG_SIZE
  4213. , sc
  4214. );
  4215. dwMaxQuorumLogSize = CLUSTER_QUORUM_DEFAULT_MAX_LOG_SIZE;
  4216. }
  4217. sc = TW32( SetClusterQuorumResource( hResource, NULL, dwMaxQuorumLogSize ) );
  4218. if ( sc != ERROR_SUCCESS )
  4219. {
  4220. hr = HRESULT_FROM_WIN32( sc );
  4221. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  4222. TASKID_Minor_HrPostCreateResourceAndDependents_SetClusterQuorumResource,
  4223. hr,
  4224. L"[PC-PostCreate] %1!ws!: Failure setting resource to be the quorum resource.",
  4225. bstrNotification,
  4226. bstrName
  4227. );
  4228. STATUS_REPORT_MINOR_REF_POSTCFG1(
  4229. TASKID_Minor_Starting_Resources
  4230. , IDS_TASKID_MINOR_ERROR_SET_QUORUM_RES
  4231. , IDS_REF_MINOR_ERROR_SET_QUORUM_RES
  4232. , hr
  4233. , bstrName
  4234. );
  4235. }
  4236. else
  4237. {
  4238. SSR_LOG1(
  4239. TASKID_Major_Client_And_Server_Log
  4240. , TASKID_Minor_HrPostCreateResourceAndDependents_SetClusterQuorumResource_Succeeded
  4241. , hr
  4242. , L"[PC-PostCreate] %1!ws!: Successfully set as quorum resource."
  4243. , bstrNotification
  4244. , bstrName
  4245. );
  4246. }
  4247. //
  4248. // Create a notification about setting the quorum resource.
  4249. //
  4250. hr = THR( HrFormatMessageIntoBSTR( g_hInstance,
  4251. IDS_TASKID_MINOR_SET_QUORUM_DEVICE,
  4252. &bstrNotification,
  4253. bstrName
  4254. ) );
  4255. if ( FAILED( hr ) )
  4256. {
  4257. SSR_LOG_ERR(
  4258. TASKID_Major_Client_And_Server_Log
  4259. , TASKID_Minor_HrPostCreateResourceAndDependents_FormatMessage_SetQuorum
  4260. , hr
  4261. , L"Failed to format a message for quorum resource."
  4262. );
  4263. STATUS_REPORT_POSTCFG(
  4264. TASKID_Major_Configure_Resources
  4265. , TASKID_Minor_HrPostCreateResourceAndDependents_FormatMessage_SetQuorum
  4266. , IDS_TASKID_MINOR_ERROR_FORMAT_STRING
  4267. , hr
  4268. );
  4269. // ignore the failure.
  4270. }
  4271. //
  4272. // Send a status that we found the quorum device.
  4273. //
  4274. hr = THR( SendStatusReport( NULL,
  4275. TASKID_Major_Configure_Resources,
  4276. TASKID_Minor_Set_Quorum_Device,
  4277. 5,
  4278. 5,
  4279. 5,
  4280. HRESULT_FROM_WIN32( sc ),
  4281. bstrNotification,
  4282. NULL,
  4283. NULL
  4284. ) );
  4285. if ( hr == E_ABORT )
  4286. {
  4287. goto Cleanup;
  4288. }
  4289. // ignore failure
  4290. // Do this only if the quorum has changed.
  4291. if ( ( sc == ERROR_SUCCESS ) && ( m_ecmCommitChangesMode == cmCREATE_CLUSTER ) && ( m_fIsQuorumChanged == TRUE ) )
  4292. {
  4293. TraceFlow( "We are forming a cluster and the quorum resouce has changed - trying to delete the local quorum resource." );
  4294. m_dwLocalQuorumStatusMax = 62; // one status message, base-zero offset (1), plus up to 60 one-second retries
  4295. //
  4296. // If we are here, we are forming and we have successfully set a new quorum resource.
  4297. // So, delete the local quorum resource.
  4298. //
  4299. // Create a notification about deleting the local quorum resource.
  4300. hr = THR( HrFormatMessageIntoBSTR( g_hInstance, IDS_DELETING_LOCAL_QUORUM_RESOURCE, &bstrLocalQuorumNotification ) );
  4301. // ignore the failure.
  4302. // Send a status that we are deleting the quorum device.
  4303. hr = THR( SendStatusReport( NULL,
  4304. TASKID_Major_Configure_Resources,
  4305. TASKID_Minor_Delete_LocalQuorum,
  4306. 0,
  4307. m_dwLocalQuorumStatusMax,
  4308. 0,
  4309. HRESULT_FROM_WIN32( sc ),
  4310. bstrLocalQuorumNotification,
  4311. NULL,
  4312. NULL
  4313. ) );
  4314. //
  4315. // KB: GPotts 01-May-2002
  4316. //
  4317. // This will enumerate all Local Quorum resources and delete them. We're assuming
  4318. // that only one will be created and thus only one will be deleted since we're executing
  4319. // inside an 'if mode == create' block. If the create behavior changes in the future
  4320. // to create multiple LQ resources then the SendStatusReport calls here and in the
  4321. // S_ScDeleteLocalQuorumResource function will need to modified accordingly to
  4322. // reflect a more appropriate max count and properly track the current count.
  4323. //
  4324. sc = TW32(
  4325. ResUtilEnumResourcesEx(
  4326. m_hCluster
  4327. , NULL
  4328. , CLUS_RESTYPE_NAME_LKQUORUM
  4329. , S_ScDeleteLocalQuorumResource
  4330. , this
  4331. )
  4332. );
  4333. if ( sc != ERROR_SUCCESS )
  4334. {
  4335. LogMsg( "[PC-PostCfg] An error occurred trying to enumerate local quorum resources (sc=%#08x).", sc );
  4336. STATUS_REPORT_MINOR_POSTCFG(
  4337. TASKID_Minor_Starting_Resources
  4338. , IDS_TASKID_MINOR_ERROR_ENUM_QUORUM
  4339. , hr
  4340. );
  4341. } // if: an error occurred trying to enumerate all local quorum resources
  4342. else
  4343. {
  4344. LogMsg( "[PC-PostCfg] Successfully deleted the local quorum resource." );
  4345. } // if: we successfully deleted the localquorum resource
  4346. // Complete the status that we are deleting the quorum device.
  4347. hr = THR( SendStatusReport( NULL,
  4348. TASKID_Major_Configure_Resources,
  4349. TASKID_Minor_Delete_LocalQuorum,
  4350. 0,
  4351. m_dwLocalQuorumStatusMax,
  4352. m_dwLocalQuorumStatusMax,
  4353. HRESULT_FROM_WIN32( sc ),
  4354. NULL, // don't update text
  4355. NULL,
  4356. NULL
  4357. ) );
  4358. } // if: we are forming a cluster and there have been no errors setting the quorum resource
  4359. hr = THR( SendStatusReport( NULL,
  4360. TASKID_Major_Configure_Resources,
  4361. TASKID_Minor_Locate_Existing_Quorum_Device,
  4362. 10,
  4363. 10,
  4364. 10,
  4365. hr,
  4366. NULL, // don't update text
  4367. NULL,
  4368. NULL
  4369. ) );
  4370. if ( hr == E_ABORT )
  4371. goto Cleanup;
  4372. // ignore failure
  4373. }
  4374. //
  4375. // Some resource that we pre-create don't have an associated
  4376. // managed resource. Skip "creating" them but do create their
  4377. // dependents.
  4378. //
  4379. // Don't wrap - this can fail with Win32 ERROR_INVALID_DATA if the pointer is invalid.
  4380. hr = presentry->GetAssociatedResource( &pccmrc );
  4381. if ( FAILED( hr ) && hr != HRESULT_FROM_WIN32( ERROR_INVALID_DATA ) )
  4382. {
  4383. THR( hr );
  4384. SSR_LOG_ERR(
  4385. TASKID_Major_Client_And_Server_Log
  4386. , TASKID_Minor_HrPostCreateResourceAndDependents_GetAssociatedResource
  4387. , hr
  4388. , L"Failed to get an associated resource."
  4389. );
  4390. STATUS_REPORT_MINOR_REF_POSTCFG(
  4391. TASKID_Minor_Starting_Resources
  4392. , IDS_TASKID_MINOR_ERROR_GET_ASSOC_RES
  4393. , IDS_REF_MINOR_ERROR_GET_ASSOC_RES
  4394. , hr
  4395. );
  4396. goto Error;
  4397. }
  4398. if ( SUCCEEDED( hr ) )
  4399. {
  4400. //
  4401. // Create a service object for this resource.
  4402. //
  4403. hr = THR( CPostCreateServices::S_HrCreateInstance( &punkServices ) );
  4404. if ( FAILED( hr ) )
  4405. {
  4406. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log,
  4407. TASKID_Minor_HrPostCreateResourceAndDependents_Create_CPostCreateServices,
  4408. hr,
  4409. L"[PC-PostCreate] Failed to create services object. Aborting."
  4410. );
  4411. STATUS_REPORT_MINOR_REF_POSTCFG(
  4412. TASKID_Minor_Starting_Resources
  4413. , IDS_TASKID_MINOR_ERROR_CREATE_SERVICE
  4414. , IDS_REF_MINOR_ERROR_CREATE_SERVICE
  4415. , hr
  4416. );
  4417. goto Error;
  4418. }
  4419. hr = THR( punkServices->TypeSafeQI( IPrivatePostCfgResource, &ppcr ) );
  4420. if ( FAILED( hr ) )
  4421. {
  4422. SSR_LOG_ERR(
  4423. TASKID_Major_Client_And_Server_Log
  4424. , TASKID_Minor_HrPostCreateResourceAndDependents_Create_CPostCreateServices_QI_ppcr
  4425. , hr
  4426. , L"[PC-PostCreate] Failed to get IPrivatePostCfgResource. Aborting."
  4427. );
  4428. STATUS_REPORT_MINOR_REF_POSTCFG(
  4429. TASKID_Minor_Starting_Resources
  4430. , IDS_TASKID_MINOR_ERROR_CREATE_SERVICE
  4431. , IDS_REF_MINOR_ERROR_CREATE_SERVICE
  4432. , hr
  4433. );
  4434. goto Error;
  4435. }
  4436. hr = THR( ppcr->SetEntry( presentry ) );
  4437. if ( FAILED( hr ) )
  4438. {
  4439. SSR_LOG_ERR(
  4440. TASKID_Major_Client_And_Server_Log
  4441. , TASKID_Minor_HrPostCreateResourceAndDependents_SetEntry
  4442. , hr
  4443. , L"[PC-PostCreate] Failed to set entry for private post configuration resource."
  4444. );
  4445. STATUS_REPORT_MINOR_REF_POSTCFG(
  4446. TASKID_Minor_Starting_Resources
  4447. , IDS_TASKID_MINOR_ERROR_POST_SETENTRY
  4448. , IDS_REF_MINOR_ERROR_POST_SETENTRY
  4449. , hr
  4450. );
  4451. goto Error;
  4452. }
  4453. // Don't wrap - this can fail with E_NOTIMPL.
  4454. hr = pccmrc->PostCreate( punkServices );
  4455. if ( FAILED( hr ) )
  4456. {
  4457. if ( hr == E_NOTIMPL )
  4458. {
  4459. SSR_LOG1(
  4460. TASKID_Major_Client_And_Server_Log
  4461. , TASKID_Minor_HrPostCreateResourceAndDependents_PostCreate_E_NOTIMPL
  4462. , hr
  4463. , L"[PC-PostCreate] %1!ws!: PostCreate() returned E_NOTIMPL. Ignoring."
  4464. , bstrNotification
  4465. , bstrName
  4466. );
  4467. } // if: E_NOTIMPL
  4468. else
  4469. {
  4470. SSR_LOG1(
  4471. TASKID_Major_Client_And_Server_Log
  4472. , TASKID_Minor_HrPostCreateResourceAndDependents_PostCreate_Failed
  4473. , hr
  4474. , L"[PC-PostCreate] %1!ws!: PostCreate() failed. Ignoring."
  4475. , bstrNotification
  4476. , bstrName
  4477. );
  4478. STATUS_REPORT_REF_POSTCFG1(
  4479. TASKID_Minor_Starting_Resources
  4480. , TASKID_Minor_Resource_Failed_PostCreate
  4481. , IDS_TASKID_MINOR_RESOURCE_FAILED_POSTCREATE
  4482. , IDS_REF_MINOR_RESOURCE_FAILED_POSTCREATE
  4483. , hr
  4484. , bstrName
  4485. );
  4486. } // else: other failure
  4487. } // if: failure
  4488. else
  4489. {
  4490. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  4491. TASKID_Minor_HrPostCreateResourceAndDependents_PostCreate_Succeeded,
  4492. hr,
  4493. L"[PC-PostCreate] %1!ws!: PostCreate() succeeded.",
  4494. bstrNotification,
  4495. bstrName
  4496. );
  4497. } // else: success
  4498. } // if: inteface
  4499. else
  4500. {
  4501. if ( hr == HRESULT_FROM_WIN32( ERROR_INVALID_DATA ) )
  4502. {
  4503. hr = S_OK;
  4504. }
  4505. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  4506. TASKID_Minor_HrPostCreateResourceAndDependents_PostCreate_NotNeeded,
  4507. hr,
  4508. L"[PC-PostCreate] %1!ws!: No PostCreate() needed. Configuring dependents.",
  4509. bstrNotification,
  4510. bstrName
  4511. );
  4512. } // else: no interface
  4513. } // if: not created
  4514. //
  4515. // Now that we created the resource instance, we need to create its dependents.
  4516. //
  4517. hr = THR( presentry->GetCountOfDependents( &cDependents ) );
  4518. if ( FAILED( hr ) )
  4519. {
  4520. SSR_LOG_ERR(
  4521. TASKID_Major_Client_And_Server_Log
  4522. , TASKID_Minor_HrPostCreateResourceAndDependents_GetCountOfDependents
  4523. , hr
  4524. , L"[PC-PostCreate] Failed to get count of resource instance dependents."
  4525. );
  4526. STATUS_REPORT_REF_POSTCFG(
  4527. TASKID_Minor_Starting_Resources
  4528. , TASKID_Minor_HrPostCreateResourceAndDependents_GetCountOfDependents
  4529. , IDS_TASKID_MINOR_ERROR_COUNT_OF_DEPENDENTS
  4530. , IDS_REF_MINOR_ERROR_COUNT_OF_DEPENDENTS
  4531. , hr
  4532. );
  4533. goto Error;
  4534. }
  4535. for( ; cDependents != 0; )
  4536. {
  4537. cDependents --;
  4538. hr = THR( presentry->GetDependent( cDependents, &idxDependent, &dfDependent ) );
  4539. if ( FAILED( hr ) )
  4540. {
  4541. SSR_LOG_ERR(
  4542. TASKID_Major_Client_And_Server_Log
  4543. , TASKID_Minor_HrPostCreateResourceAndDependents_GetDependent
  4544. , hr
  4545. , L"[PC-PostCreate] Failed to get a resource dependent."
  4546. );
  4547. STATUS_REPORT_MINOR_REF_POSTCFG(
  4548. TASKID_Minor_Starting_Resources
  4549. , IDS_TASKID_MINOR_ERROR_GET_DEPENDENT
  4550. , IDS_REF_MINOR_ERROR_GET_DEPENDENT
  4551. , hr
  4552. );
  4553. continue;
  4554. }
  4555. hr = THR( HrPostCreateResourceAndDependents( idxDependent ) );
  4556. if ( FAILED( hr ) )
  4557. continue;
  4558. } // for: cDependents
  4559. //
  4560. // Update the UI layer.
  4561. //
  4562. m_cResourcesConfigured++;
  4563. hr = THR( SendStatusReport( NULL,
  4564. TASKID_Major_Configure_Resources,
  4565. TASKID_Minor_Starting_Resources,
  4566. 0,
  4567. m_cResources + 2,
  4568. m_cResourcesConfigured,
  4569. S_OK,
  4570. NULL, // don't need to change text
  4571. NULL,
  4572. NULL
  4573. ) );
  4574. if ( hr == E_ABORT )
  4575. {
  4576. // ignore failure
  4577. goto Cleanup;
  4578. }
  4579. hr = S_OK;
  4580. Cleanup:
  4581. if ( pccmrc != NULL )
  4582. {
  4583. pccmrc->Release();
  4584. }
  4585. if ( punkServices != NULL )
  4586. {
  4587. punkServices->Release();
  4588. }
  4589. if ( ppcr != NULL )
  4590. {
  4591. ppcr->Release();
  4592. }
  4593. TraceSysFreeString( bstrNotification );
  4594. TraceSysFreeString( bstrLocalQuorumNotification );
  4595. HRETURN( hr );
  4596. Error:
  4597. m_cResourcesConfigured++;
  4598. THR( SendStatusReport( NULL,
  4599. TASKID_Major_Configure_Resources,
  4600. TASKID_Minor_Starting_Resources,
  4601. 0,
  4602. m_cResources + 2,
  4603. m_cResourcesConfigured,
  4604. hr,
  4605. NULL, // don't need to change text
  4606. NULL,
  4607. NULL
  4608. ) );
  4609. goto Cleanup;
  4610. } //*** CPostCfgManager::HrPostCreateResourceAndDependents
  4611. //////////////////////////////////////////////////////////////////////////////
  4612. //++
  4613. //
  4614. // HRESULT
  4615. // CPostCfgManager::HrNotifyMemberSetChangeListeners
  4616. //
  4617. // Description:
  4618. // Notify all components on the local computer registered to get
  4619. // notification of cluster member set change (form, join or evict).
  4620. //
  4621. // Arguments:
  4622. // None.
  4623. //
  4624. // Return Values:
  4625. // S_OK
  4626. // Success.
  4627. //
  4628. // other HRESULTs
  4629. // Something went wrong during the notifications.
  4630. //
  4631. //--
  4632. //////////////////////////////////////////////////////////////////////////////
  4633. HRESULT
  4634. CPostCfgManager::HrNotifyMemberSetChangeListeners( void )
  4635. {
  4636. TraceFunc( "" );
  4637. const UINT uiCHUNK_SIZE = 16;
  4638. HRESULT hr = S_OK;
  4639. ICatInformation * pciCatInfo = NULL;
  4640. IEnumCLSID * plceListenerClsidEnum = NULL;
  4641. ULONG cReturned = 0;
  4642. CATID rgCatIdsImplemented[ 1 ];
  4643. // Validate state
  4644. Assert( m_pccci != NULL );
  4645. rgCatIdsImplemented[ 0 ] = CATID_ClusCfgMemberSetChangeListeners;
  4646. //
  4647. // Enumerate all the enumerators registered in the
  4648. // CATID_ClusCfgMemberSetChangeListeners category
  4649. //
  4650. hr = THR(
  4651. CoCreateInstance(
  4652. CLSID_StdComponentCategoriesMgr
  4653. , NULL
  4654. , CLSCTX_SERVER
  4655. , IID_ICatInformation
  4656. , reinterpret_cast< void ** >( &pciCatInfo )
  4657. )
  4658. );
  4659. if ( FAILED( hr ) )
  4660. {
  4661. SSR_LOG_ERR(
  4662. TASKID_Major_Client_And_Server_Log
  4663. , TASKID_Minor_HrNotifyMemberSetChangeListeners_CoCreate_StdComponentCategoriesMgr
  4664. , hr
  4665. , L"Error occurred trying to get a pointer to the enumerator of the CATID_ClusCfgMemberSetChangeListeners category."
  4666. );
  4667. STATUS_REPORT_REF_POSTCFG(
  4668. TASKID_Major_Configure_Resources
  4669. , TASKID_Minor_HrNotifyMemberSetChangeListeners_CoCreate_StdComponentCategoriesMgr
  4670. , IDS_TASKID_MINOR_ERROR_COMPONENT_CATEGORY_MGR
  4671. , IDS_REF_MINOR_ERROR_COMPONENT_CATEGORY_MGR
  4672. , hr
  4673. );
  4674. goto Cleanup;
  4675. } // if: we could not get a pointer to the ICatInformation interface
  4676. // Get a pointer to the enumerator of the CLSIDs that belong to
  4677. // the CATID_ClusCfgMemberSetChangeListeners category.
  4678. hr = THR(
  4679. pciCatInfo->EnumClassesOfCategories(
  4680. 1
  4681. , rgCatIdsImplemented
  4682. , 0
  4683. , NULL
  4684. , &plceListenerClsidEnum
  4685. )
  4686. );
  4687. if ( FAILED( hr ) )
  4688. {
  4689. SSR_LOG_ERR(
  4690. TASKID_Major_Client_And_Server_Log
  4691. , TASKID_Minor_HrNotifyMemberSetChangeListeners_EnumClassesOfCategories
  4692. , hr
  4693. , L"Error occurred trying to get a pointer to the enumerator of the CATID_ClusCfgMemberSetChangeListeners category."
  4694. );
  4695. STATUS_REPORT_REF_POSTCFG(
  4696. TASKID_Major_Configure_Resources
  4697. , TASKID_Minor_HrNotifyMemberSetChangeListeners_EnumClassesOfCategories
  4698. , IDS_TASKID_MINOR_ERROR_COMPONENT_ENUM_CLASS
  4699. , IDS_REF_MINOR_ERROR_COMPONENT_ENUM_CLASS
  4700. , hr
  4701. );
  4702. goto Cleanup;
  4703. } // if: we could not get a pointer to the IEnumCLSID interface
  4704. // Enumerate the CLSIDs of the registered enumerators
  4705. do
  4706. {
  4707. CLSID rgListenerClsidArray[ uiCHUNK_SIZE ];
  4708. ULONG idxCLSID;
  4709. hr = STHR(
  4710. plceListenerClsidEnum->Next(
  4711. uiCHUNK_SIZE
  4712. , rgListenerClsidArray
  4713. , &cReturned
  4714. )
  4715. );
  4716. if ( FAILED( hr ) )
  4717. {
  4718. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log,
  4719. TASKID_Minor_HrNotifyMemberSetChangeListeners_Next,
  4720. hr,
  4721. L"Error occurred trying enumerate member set listener enumerators."
  4722. );
  4723. STATUS_REPORT_MINOR_REF_POSTCFG(
  4724. TASKID_Major_Configure_Resources
  4725. , IDS_TASKID_MINOR_ERROR_NEXT_LISTENER
  4726. , IDS_REF_MINOR_ERROR_NEXT_LISTENER
  4727. , hr
  4728. );
  4729. break;
  4730. } // if: we could not get a pointer to the IEnumCLSID interface
  4731. // hr may be S_FALSE here, so reset it.
  4732. hr = S_OK;
  4733. for ( idxCLSID = 0; idxCLSID < cReturned; ++idxCLSID )
  4734. {
  4735. hr = THR( HrProcessMemberSetChangeListener( rgListenerClsidArray[ idxCLSID ] ) );
  4736. if ( FAILED( hr ) )
  4737. {
  4738. // The processing of one of the listeners failed.
  4739. // Log the error, but continue processing other listeners.
  4740. SSR_LOG_ERR(
  4741. TASKID_Major_Client_And_Server_Log
  4742. , TASKID_Minor_HrNotifyMemberSetChangeListeners_HrProcessMemberSetChangeListener
  4743. , hr
  4744. , L"Error occurred trying to process a member set change listener. Ignoring. Other listeners will be processed."
  4745. );
  4746. STATUS_REPORT_MINOR_REF_POSTCFG(
  4747. TASKID_Major_Configure_Resources
  4748. , IDS_TASKID_MINOR_ERROR_PROCESS_LISTENER
  4749. , IDS_REF_MINOR_ERROR_PROCESS_LISTENER
  4750. , hr
  4751. );
  4752. hr = S_OK;
  4753. } // if: this listener failed
  4754. } // for: iterate through the returned CLSIDs
  4755. }
  4756. while( cReturned > 0 ); // while: there are still CLSIDs to be enumerated
  4757. if ( FAILED( hr ) )
  4758. {
  4759. goto Cleanup;
  4760. } // if: something went wrong in the loop above
  4761. Cleanup:
  4762. //
  4763. // Cleanup code
  4764. //
  4765. if ( pciCatInfo != NULL )
  4766. {
  4767. pciCatInfo->Release();
  4768. } // if: we had obtained a pointer to the ICatInformation interface
  4769. if ( plceListenerClsidEnum != NULL )
  4770. {
  4771. plceListenerClsidEnum->Release();
  4772. } // if: we had obtained a pointer to the enumerator of listener CLSIDs
  4773. HRETURN( hr );
  4774. } //*** CPostCfgManager::HrNotifyMemberSetChangeListeners
  4775. //////////////////////////////////////////////////////////////////////////////
  4776. //++
  4777. //
  4778. // HRESULT
  4779. // CPostCfgManager::HrProcessMemberSetChangeListener
  4780. //
  4781. // Description:
  4782. // This function notifies a listener of cluster member set changes.
  4783. //
  4784. // Arguments:
  4785. // rclsidListenerClsidIn
  4786. // CLSID of the listener component.
  4787. //
  4788. // Return Values:
  4789. // S_OK
  4790. // Success.
  4791. //
  4792. // other HRESULTs
  4793. // Something went wrong during the notification.
  4794. //
  4795. //--
  4796. //////////////////////////////////////////////////////////////////////////////
  4797. HRESULT
  4798. CPostCfgManager::HrProcessMemberSetChangeListener(
  4799. const CLSID & rclsidListenerClsidIn
  4800. )
  4801. {
  4802. TraceFunc( "" );
  4803. HRESULT hr = S_OK;
  4804. IClusCfgMemberSetChangeListener * pccmclListener = NULL;
  4805. IClusCfgInitialize * picci = NULL;
  4806. TraceMsgGUID( mtfFUNC, "The CLSID of this listener is ", rclsidListenerClsidIn );
  4807. //
  4808. // Create the listener represented by the CLSID passed in
  4809. //
  4810. hr = THR(
  4811. CoCreateInstance(
  4812. rclsidListenerClsidIn
  4813. , NULL
  4814. , CLSCTX_INPROC_SERVER
  4815. , __uuidof( pccmclListener )
  4816. , reinterpret_cast< void ** >( &pccmclListener )
  4817. )
  4818. );
  4819. if ( FAILED( hr ) )
  4820. {
  4821. SSR_LOG_ERR(
  4822. TASKID_Major_Client_And_Server_Log
  4823. , TASKID_Minor_HrProcessMemberSetChangeListener_CoCreate_Listener
  4824. , hr
  4825. , L"Error occurred trying to get a pointer to the the member set change listener."
  4826. );
  4827. STATUS_REPORT_MINOR_REF_POSTCFG(
  4828. TASKID_Major_Configure_Resources
  4829. , IDS_TASKID_MINOR_ERROR_GET_LISTENER_PTR
  4830. , IDS_REF_MINOR_ERROR_GET_LISTENER_PTR
  4831. , hr
  4832. );
  4833. goto Cleanup;
  4834. } // if: we could not get a pointer to the IClusCfgMemberSetChangeListener interface
  4835. //
  4836. // If the component wants to be initialized, i.e. they implement
  4837. // IClusCfgInitiaze, then we should initialize them. If they
  4838. // don't want to be initialized then skip it.
  4839. //
  4840. hr = pccmclListener->TypeSafeQI( IClusCfgInitialize, &picci );
  4841. if ( SUCCEEDED( hr ) )
  4842. {
  4843. hr = THR( picci->Initialize( m_pcccb, m_lcid ) );
  4844. if ( FAILED( hr ) )
  4845. {
  4846. goto Cleanup;
  4847. } // if:
  4848. } // if: Interface found.
  4849. else if ( hr == E_NOINTERFACE )
  4850. {
  4851. //
  4852. // Component does not want to be initialized.
  4853. //
  4854. hr = S_OK;
  4855. } // else if: No interface.
  4856. else
  4857. {
  4858. //
  4859. // QI failed with an unexpected error.
  4860. //
  4861. THR( hr );
  4862. goto Cleanup;
  4863. } // else: QI failed.
  4864. hr = THR( pccmclListener->Notify( m_pccci ) );
  4865. if ( FAILED( hr ) )
  4866. {
  4867. // The processing of this listeners failed.
  4868. SSR_LOG_ERR(
  4869. TASKID_Major_Client_And_Server_Log
  4870. , TASKID_Minor_HrProcessMemberSetChangeListener_Notify
  4871. , hr
  4872. , L"Error occurred trying to notify a listener."
  4873. );
  4874. STATUS_REPORT_MINOR_REF_POSTCFG(
  4875. TASKID_Major_Configure_Resources
  4876. , IDS_TASKID_MINOR_ERROR_NOTIFY_LISTENER
  4877. , IDS_REF_MINOR_ERROR_NOTIFY_LISTENER
  4878. , hr
  4879. );
  4880. goto Cleanup;
  4881. } // if: this listeners failed
  4882. Cleanup:
  4883. //
  4884. // Cleanup code
  4885. //
  4886. if ( picci != NULL )
  4887. {
  4888. picci->Release();
  4889. } // if:
  4890. if ( pccmclListener != NULL )
  4891. {
  4892. pccmclListener->Release();
  4893. } // if: we had obtained a pointer to the listener interface
  4894. HRETURN( hr );
  4895. } //*** CPostCfgManager::HrProcessMemberSetChangeListener
  4896. //////////////////////////////////////////////////////////////////////////////
  4897. //++
  4898. //
  4899. // HRESULT
  4900. // CPostCfgManager::HrConfigureResTypes
  4901. //
  4902. // Description:
  4903. // Enumerate all components on the local computer registered for resource
  4904. // type configuration.
  4905. //
  4906. // Arguments:
  4907. // IUnknown * punkResTypeServicesIn
  4908. // A pointer to the IUnknown interface on a component that provides
  4909. // services that help configure resource types.
  4910. //
  4911. // Return Values:
  4912. // S_OK
  4913. // Success.
  4914. //
  4915. // other HRESULTs
  4916. // Something went wrong during the enumeration.
  4917. //
  4918. //--
  4919. //////////////////////////////////////////////////////////////////////////////
  4920. HRESULT
  4921. CPostCfgManager::HrConfigureResTypes( IUnknown * punkResTypeServicesIn )
  4922. {
  4923. TraceFunc( "" );
  4924. const UINT uiCHUNK_SIZE = 16;
  4925. HRESULT hr = S_OK;
  4926. ICatInformation * pciCatInfo = NULL;
  4927. IEnumCLSID * prceResTypeClsidEnum = NULL;
  4928. ULONG cReturned = 0;
  4929. CATID rgCatIdsImplemented[ 1 ];
  4930. // Validate state
  4931. Assert( m_pccci != NULL );
  4932. rgCatIdsImplemented[ 0 ] = CATID_ClusCfgResourceTypes;
  4933. //
  4934. // Enumerate all the enumerators registered in the
  4935. // CATID_ClusCfgResourceTypes category
  4936. //
  4937. hr = THR(
  4938. CoCreateInstance(
  4939. CLSID_StdComponentCategoriesMgr
  4940. , NULL
  4941. , CLSCTX_SERVER
  4942. , IID_ICatInformation
  4943. , reinterpret_cast< void ** >( &pciCatInfo )
  4944. )
  4945. );
  4946. if ( FAILED( hr ) )
  4947. {
  4948. SSR_LOG_ERR(
  4949. TASKID_Major_Client_And_Server_Log
  4950. , TASKID_Minor_HrConfigureResTypes_CoCreate_CategoriesMgr
  4951. , hr
  4952. , L"Error occurred trying to get a pointer to the enumerator of the CATID_ClusCfgResourceTypes category."
  4953. );
  4954. STATUS_REPORT_REF_POSTCFG(
  4955. TASKID_Major_Configure_Resources
  4956. , TASKID_Minor_HrConfigureResTypes_CoCreate_CategoriesMgr
  4957. , IDS_TASKID_MINOR_ERROR_COMPONENT_CATEGORY_MGR
  4958. , IDS_REF_MINOR_ERROR_COMPONENT_CATEGORY_MGR
  4959. , hr
  4960. );
  4961. goto Cleanup;
  4962. } // if: we could not get a pointer to the ICatInformation interface
  4963. // Get a pointer to the enumerator of the CLSIDs that belong to the CATID_ClusCfgResourceTypes category.
  4964. hr = THR(
  4965. pciCatInfo->EnumClassesOfCategories(
  4966. 1
  4967. , rgCatIdsImplemented
  4968. , 0
  4969. , NULL
  4970. , &prceResTypeClsidEnum
  4971. )
  4972. );
  4973. if ( FAILED( hr ) )
  4974. {
  4975. SSR_LOG_ERR(
  4976. TASKID_Major_Client_And_Server_Log
  4977. , TASKID_Minor_HrConfigureResTypes_Enum
  4978. , hr
  4979. , L"Error occurred trying to get a pointer to the enumerator of the CATID_ClusCfgResourceTypes category."
  4980. );
  4981. STATUS_REPORT_REF_POSTCFG(
  4982. TASKID_Major_Configure_Resources
  4983. , TASKID_Minor_HrConfigureResTypes_Enum
  4984. , IDS_TASKID_MINOR_ERROR_COMPONENT_ENUM_CLASS
  4985. , IDS_REF_MINOR_ERROR_COMPONENT_ENUM_CLASS
  4986. , hr
  4987. );
  4988. goto Cleanup;
  4989. } // if: we could not get a pointer to the IEnumCLSID interface
  4990. // Enumerate the CLSIDs of the registered resource types
  4991. do
  4992. {
  4993. CLSID rgResTypeCLSIDArray[ uiCHUNK_SIZE ];
  4994. ULONG idxCLSID;
  4995. cReturned = 0;
  4996. hr = STHR(
  4997. prceResTypeClsidEnum->Next(
  4998. uiCHUNK_SIZE
  4999. , rgResTypeCLSIDArray
  5000. , &cReturned
  5001. )
  5002. );
  5003. if ( FAILED( hr ) )
  5004. {
  5005. SSR_LOG_ERR(
  5006. TASKID_Major_Client_And_Server_Log
  5007. , TASKID_Minor_HrConfigureResTypes_Next
  5008. , hr
  5009. , L"Error occurred trying enumerate resource type configuration components."
  5010. );
  5011. STATUS_REPORT_MINOR_REF_POSTCFG(
  5012. TASKID_Major_Configure_Resources
  5013. , IDS_TASKID_MINOR_ERROR_NEXT_LISTENER
  5014. , IDS_REF_MINOR_ERROR_NEXT_LISTENER
  5015. , hr
  5016. );
  5017. break;
  5018. } // if: we could not get the next set of CLSIDs
  5019. // hr may be S_FALSE here, so reset it.
  5020. hr = S_OK;
  5021. for ( idxCLSID = 0; idxCLSID < cReturned; ++idxCLSID )
  5022. {
  5023. hr = THR( HrProcessResType( rgResTypeCLSIDArray[ idxCLSID ], punkResTypeServicesIn ) );
  5024. if ( FAILED( hr ) )
  5025. {
  5026. LPWSTR pszCLSID = NULL;
  5027. BSTR bstrNotification = NULL;
  5028. THR( StringFromCLSID( rgResTypeCLSIDArray[ idxCLSID ], &pszCLSID ) );
  5029. // The processing of one of the resource types failed.
  5030. // Log the error, but continue processing other resource types.
  5031. SSR_LOG1(
  5032. TASKID_Major_Client_And_Server_Log
  5033. , TASKID_Minor_HrConfigureResTypes_HrProcessResType
  5034. , hr
  5035. , L"[PC-ResType] Error occurred trying to process a resource type. Ignoring. Other resource types will be processed. The CLSID of the failed resource type is %1!ws!."
  5036. , bstrNotification
  5037. , pszCLSID
  5038. );
  5039. STATUS_REPORT_MINOR_REF_POSTCFG1(
  5040. TASKID_Major_Configure_Resources
  5041. , IDS_TASKID_MINOR_ERROR_PROCESS_RESOURCE_TYPE
  5042. , IDS_REF_MINOR_ERROR_PROCESS_RESOURCE_TYPE
  5043. , hr
  5044. , pszCLSID
  5045. );
  5046. TraceSysFreeString( bstrNotification );
  5047. CoTaskMemFree( pszCLSID );
  5048. hr = S_OK;
  5049. } // if: this enumerator failed
  5050. } // for: iterate through the returned CLSIDs
  5051. }
  5052. while( cReturned > 0 ); // while: there are still CLSIDs to be enumerated
  5053. if ( FAILED( hr ) )
  5054. {
  5055. goto Cleanup;
  5056. } // if: something went wrong in the loop above
  5057. Cleanup:
  5058. //
  5059. // Cleanup code
  5060. //
  5061. if ( pciCatInfo != NULL )
  5062. {
  5063. pciCatInfo->Release();
  5064. } // if: we had obtained a pointer to the ICatInformation interface
  5065. if ( prceResTypeClsidEnum != NULL )
  5066. {
  5067. prceResTypeClsidEnum->Release();
  5068. } // if: we had obtained a pointer to the enumerator of resource type CLSIDs
  5069. HRETURN( hr );
  5070. } //*** CPostCfgManager::HrConfigureResTypes
  5071. //////////////////////////////////////////////////////////////////////////////
  5072. //++
  5073. //
  5074. // HRESULT
  5075. // CPostCfgManager::HrProcessResType
  5076. //
  5077. // Description:
  5078. // This function instantiates a resource type configuration component
  5079. // and calls the appropriate methods.
  5080. //
  5081. // Arguments:
  5082. // rclsidResTypeCLSIDIn
  5083. // CLSID of the resource type configuration component
  5084. //
  5085. // punkResTypeServicesIn
  5086. // Pointer to the IUnknown interface on the resource type services
  5087. // component. This interface provides methods that help configure
  5088. // resource types.
  5089. //
  5090. // Return Values:
  5091. // S_OK
  5092. // Success.
  5093. //
  5094. // other HRESULTs
  5095. // Something went wrong during the processing of the resource type.
  5096. //
  5097. //--
  5098. //////////////////////////////////////////////////////////////////////////////
  5099. HRESULT
  5100. CPostCfgManager::HrProcessResType(
  5101. const CLSID & rclsidResTypeCLSIDIn
  5102. , IUnknown * punkResTypeServicesIn
  5103. )
  5104. {
  5105. TraceFunc( "" );
  5106. HRESULT hr = S_OK;
  5107. IClusCfgResourceTypeInfo * pcrtiResTypeInfo = NULL;
  5108. BSTR bstrResTypeName = NULL;
  5109. GUID guidResTypeGUID;
  5110. BSTR bstrNotification = NULL;
  5111. TraceMsgGUID( mtfFUNC, "The CLSID of this resource type is ", rclsidResTypeCLSIDIn );
  5112. //
  5113. // Create the component represented by the CLSID passed in
  5114. //
  5115. hr = THR(
  5116. CoCreateInstance(
  5117. rclsidResTypeCLSIDIn
  5118. , NULL
  5119. , CLSCTX_INPROC_SERVER
  5120. , __uuidof( pcrtiResTypeInfo )
  5121. , reinterpret_cast< void ** >( &pcrtiResTypeInfo )
  5122. )
  5123. );
  5124. if ( FAILED( hr ) )
  5125. {
  5126. SSR_LOG_ERR(
  5127. TASKID_Major_Client_And_Server_Log
  5128. , TASKID_Minor_HrProcessResType_CoCreate_ResTypeClsid
  5129. , hr
  5130. , L"[PC-ResType] Error occurred trying to create the resource type configuration component."
  5131. );
  5132. STATUS_REPORT_REF_POSTCFG(
  5133. TASKID_Major_Configure_Resources
  5134. , TASKID_Minor_HrProcessResType_CoCreate_ResTypeClsid
  5135. , IDS_TASKID_MINOR_ERROR_CREATE_RESOURCE_CONFIG
  5136. , IDS_REF_MINOR_ERROR_CREATE_RESOURCE_CONFIG
  5137. , hr
  5138. );
  5139. goto Cleanup;
  5140. } // if: we could not create the resource type configuration component
  5141. //
  5142. // Initialize the newly created component
  5143. //
  5144. {
  5145. IClusCfgInitialize * pcci = NULL;
  5146. HRESULT hrTemp;
  5147. // Check if this component supports the callback interface.
  5148. hrTemp = THR( pcrtiResTypeInfo->QueryInterface< IClusCfgInitialize >( &pcci ) );
  5149. if ( FAILED( hrTemp ) )
  5150. {
  5151. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log,
  5152. TASKID_Minor_HrProcessResType_QI_pcci,
  5153. hrTemp,
  5154. L"Error occurred trying to get a pointer to the IClusCfgInitialize interface. This resource type does not support initialization."
  5155. );
  5156. } // if: the callback interface is not supported
  5157. else
  5158. {
  5159. // Initialize this component.
  5160. hr = THR( pcci->Initialize( static_cast< IClusCfgCallback * >( this ), m_lcid ) );
  5161. // This interface is no longer needed.
  5162. pcci->Release();
  5163. // Did initialization succeed?
  5164. if ( FAILED( hr ) )
  5165. {
  5166. SSR_LOG_ERR(
  5167. TASKID_Major_Client_And_Server_Log
  5168. , TASKID_Minor_HrProcessResType_Initialize
  5169. , hr
  5170. , L"Error occurred trying initialize a resource type configuration component."
  5171. );
  5172. STATUS_REPORT_REF_POSTCFG(
  5173. TASKID_Major_Configure_Resources
  5174. , TASKID_Minor_HrProcessResType_Initialize
  5175. , IDS_TASKID_MINOR_ERROR_INIT_RESOURCE_CONFIG
  5176. , IDS_REF_MINOR_ERROR_INIT_RESOURCE_CONFIG
  5177. , hr
  5178. );
  5179. goto Cleanup;
  5180. } // if: the initialization failed
  5181. } // else: the callback interface is supported
  5182. }
  5183. // Get the name of the current resource type.
  5184. hr = THR( pcrtiResTypeInfo->GetTypeName( &bstrResTypeName ) );
  5185. if ( FAILED( hr ) )
  5186. {
  5187. SSR_LOG_ERR(
  5188. TASKID_Major_Client_And_Server_Log
  5189. , TASKID_Minor_HrProcessResType_GetTypeName
  5190. , hr
  5191. , L"Error occurred trying to get the name of a resource type."
  5192. );
  5193. STATUS_REPORT_REF_POSTCFG(
  5194. TASKID_Major_Configure_Resources
  5195. , TASKID_Minor_HrProcessResType_GetTypeName
  5196. , IDS_TASKID_MINOR_ERROR_GET_RESTYPE_NAME
  5197. , IDS_REF_MINOR_ERROR_GET_RESTYPE_NAME
  5198. , hr
  5199. );
  5200. goto Cleanup;
  5201. } // if: we could not get the resource type name
  5202. TraceMemoryAddBSTR( bstrResTypeName );
  5203. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  5204. TASKID_Minor_HrProcessResType_AboutToConfigureType,
  5205. hr,
  5206. L"[PC-ResType] %1!ws!: About to configure resource type...",
  5207. bstrNotification,
  5208. bstrResTypeName
  5209. );
  5210. // Configure this resource type.
  5211. hr = THR( pcrtiResTypeInfo->CommitChanges( m_pccci, punkResTypeServicesIn ) );
  5212. if ( FAILED( hr ) )
  5213. {
  5214. SSR_LOG1(
  5215. TASKID_Major_Client_And_Server_Log
  5216. , TASKID_Minor_HrProcessResType_CommitChanges
  5217. , hr
  5218. , L"[PC-ResType] %1!ws!: Error occurred trying to configure the resource type."
  5219. , bstrNotification
  5220. , bstrResTypeName
  5221. );
  5222. STATUS_REPORT_REF_POSTCFG1(
  5223. TASKID_Major_Configure_Resources
  5224. , TASKID_Minor_HrProcessResType_CommitChanges
  5225. , IDS_TASKID_MINOR_ERROR_CONFIG_RESOURCE_TYPE
  5226. , IDS_REF_MINOR_ERROR_CONFIG_RESOURCE_TYPE
  5227. , hr
  5228. , bstrResTypeName
  5229. );
  5230. goto Cleanup;
  5231. } // if: this resource type configuration failed
  5232. // Get and store the resource type GUID
  5233. hr = STHR( pcrtiResTypeInfo->GetTypeGUID( &guidResTypeGUID ) );
  5234. if ( FAILED( hr ) )
  5235. {
  5236. SSR_LOG1(
  5237. TASKID_Major_Client_And_Server_Log
  5238. , TASKID_Minor_HrProcessResType_GetTypeGUID
  5239. , hr
  5240. , L"[PC-ResType] %1!ws!: Error occurred trying to get the resource type GUID."
  5241. , bstrNotification
  5242. , bstrResTypeName
  5243. );
  5244. STATUS_REPORT_REF_POSTCFG1(
  5245. TASKID_Major_Configure_Resources
  5246. , TASKID_Minor_HrProcessResType_GetTypeGUID
  5247. , IDS_TASKID_MINOR_ERROR_RESOURCE_TYPE_GUID
  5248. , IDS_REF_MINOR_ERROR_RESOURCE_TYPE_GUID
  5249. , hr
  5250. , bstrResTypeName
  5251. );
  5252. goto Cleanup;
  5253. } // if: this resource type configuration failed
  5254. if ( hr == S_OK )
  5255. {
  5256. TraceMsgGUID( mtfFUNC, "The GUID of this resource type is", guidResTypeGUID );
  5257. hr = THR( HrMapResTypeGUIDToName( guidResTypeGUID, bstrResTypeName ) );
  5258. if ( FAILED( hr ) )
  5259. {
  5260. SSR_LOG_ERR(
  5261. TASKID_Major_Client_And_Server_Log
  5262. , TASKID_Minor_HrProcessResType_HrMapResTypeGUIDToName
  5263. , hr
  5264. , L"Error occurred trying to create a mapping between a GUID and a name"
  5265. );
  5266. STATUS_REPORT_REF_POSTCFG1(
  5267. TASKID_Major_Configure_Resources
  5268. , TASKID_Minor_HrProcessResType_HrMapResTypeGUIDToName
  5269. , IDS_TASKID_MINOR_ERROR_MAPPING_GUID_AND_NAME
  5270. , IDS_REF_MINOR_ERROR_MAPPING_GUID_AND_NAME
  5271. , hr
  5272. , bstrResTypeName
  5273. );
  5274. // Something went wrong with our code - we cannot continue.
  5275. goto Cleanup;
  5276. } // if: we could not add the mapping
  5277. } // if: this resource type has a GUID
  5278. else
  5279. {
  5280. // Reset hr
  5281. hr = S_OK;
  5282. SSR_LOG_ERR( TASKID_Major_Client_And_Server_Log,
  5283. TASKID_Minor_HrProcessResType_NoGuid,
  5284. hr,
  5285. L"This resource type does not have a GUID associated with it."
  5286. );
  5287. } // else: this resource type does not have a GUID
  5288. Cleanup:
  5289. //
  5290. // Cleanup code
  5291. //
  5292. if ( pcrtiResTypeInfo != NULL )
  5293. {
  5294. pcrtiResTypeInfo->Release();
  5295. } // if: we had obtained a pointer to the resource type info interface
  5296. TraceSysFreeString( bstrResTypeName );
  5297. TraceSysFreeString( bstrNotification );
  5298. HRETURN( hr );
  5299. } //*** CPostCfgManager::HrProcessResType
  5300. //////////////////////////////////////////////////////////////////////////////
  5301. //++
  5302. //
  5303. // HRESULT
  5304. // CPostCfgManager::HrMapResTypeGUIDToName
  5305. //
  5306. // Description:
  5307. // Create a mapping between a resource type GUID and a resource type name.
  5308. //
  5309. // Arguments:
  5310. // rcguidTypeGuidIn
  5311. // Resource type GUID which is to be mapped to a resource type name.
  5312. //
  5313. // pcszTypeNameIn
  5314. // The resource type name to map the above GUID to.
  5315. //
  5316. // Return Values:
  5317. // S_OK
  5318. // Success.
  5319. //
  5320. // other HRESULTs
  5321. // If something went wrong
  5322. //
  5323. //--
  5324. //////////////////////////////////////////////////////////////////////////////
  5325. HRESULT
  5326. CPostCfgManager::HrMapResTypeGUIDToName(
  5327. const GUID & rcguidTypeGuidIn
  5328. , const WCHAR * pcszTypeNameIn
  5329. )
  5330. {
  5331. TraceFunc( "" );
  5332. HRESULT hr = S_OK;
  5333. ULONG cchTypeNameSize;
  5334. WCHAR * pszTypeName;
  5335. //
  5336. // Validate the parameters
  5337. //
  5338. // Validate the parameters
  5339. if ( ( pcszTypeNameIn == NULL ) || ( *pcszTypeNameIn == L'\0' ) )
  5340. {
  5341. hr = THR( E_INVALIDARG );
  5342. SSR_LOG_ERR(
  5343. TASKID_Major_Client_And_Server_Log
  5344. , TASKID_HrMapResTypeGUIDToName_InvalidArg
  5345. , hr
  5346. , L"An empty resource type name can not be added to the map."
  5347. );
  5348. STATUS_REPORT_REF_POSTCFG(
  5349. TASKID_Major_Configure_Resources
  5350. , TASKID_HrMapResTypeGUIDToName_InvalidArg
  5351. , IDS_TASKID_MINOR_ERROR_EMPTY_RESTYPE_NAME
  5352. , IDS_REF_MINOR_ERROR_EMPTY_RESTYPE_NAME
  5353. , hr
  5354. );
  5355. goto Cleanup;
  5356. } // if: the resource type name is empty
  5357. // Check if the existing map buffer is big enough to hold another entry.
  5358. if ( m_idxNextMapEntry >= m_cMapSize )
  5359. {
  5360. // Double the size of the map buffer
  5361. ULONG cNewMapSize = m_cMapSize * 2;
  5362. ULONG idxMapEntry;
  5363. SResTypeGUIDAndName * pgnNewMap = new SResTypeGUIDAndName[ cNewMapSize ];
  5364. if ( pgnNewMap == NULL )
  5365. {
  5366. hr = THR( E_OUTOFMEMORY );
  5367. SSR_LOG_ERR(
  5368. TASKID_Major_Client_And_Server_Log
  5369. , TASKID_HrMapResTypeGUIDToName_OutOfMemory_NewMap
  5370. , hr
  5371. , L"Memory allocation failed trying to add a new resource type GUID to name map entry."
  5372. );
  5373. STATUS_REPORT_REF_POSTCFG(
  5374. TASKID_Major_Configure_Resources
  5375. , TASKID_HrMapResTypeGUIDToName_OutOfMemory_NewMap
  5376. , IDS_TASKID_MINOR_ERROR_OUT_OF_MEMORY
  5377. , IDS_REF_MINOR_ERROR_OUT_OF_MEMORY
  5378. , hr
  5379. );
  5380. goto Cleanup;
  5381. } // if: memory allocation failed
  5382. // Copy the contents of the old buffer to the new one.
  5383. for ( idxMapEntry = 0; idxMapEntry < m_idxNextMapEntry; ++idxMapEntry )
  5384. {
  5385. pgnNewMap[ idxMapEntry ] = m_pgnResTypeGUIDNameMap[ idxMapEntry ];
  5386. } // for: iterate through the existing map
  5387. // Update the member variables
  5388. delete [] m_pgnResTypeGUIDNameMap;
  5389. m_pgnResTypeGUIDNameMap = pgnNewMap;
  5390. m_cMapSize = cNewMapSize;
  5391. } // if: the map buffer is not big enough for another entry
  5392. //
  5393. // Add the new entry to the map
  5394. //
  5395. // Since resource type names are unlimited we won't use the strsafe functions here.
  5396. cchTypeNameSize = (ULONG)(wcslen( pcszTypeNameIn ) + 1);
  5397. pszTypeName = new WCHAR[ cchTypeNameSize ];
  5398. if ( pszTypeName == NULL )
  5399. {
  5400. hr = THR( E_OUTOFMEMORY );
  5401. SSR_LOG_ERR(
  5402. TASKID_Major_Client_And_Server_Log
  5403. , TASKID_HrMapResTypeGUIDToName_OutOfMemory_TypeName
  5404. , hr
  5405. , L"Memory allocation failed trying to add a new resource type GUID to name map entry."
  5406. );
  5407. STATUS_REPORT_REF_POSTCFG(
  5408. TASKID_Major_Configure_Resources
  5409. , TASKID_HrMapResTypeGUIDToName_OutOfMemory_TypeName
  5410. , IDS_TASKID_MINOR_ERROR_OUT_OF_MEMORY
  5411. , IDS_REF_MINOR_ERROR_OUT_OF_MEMORY
  5412. , hr
  5413. );
  5414. goto Cleanup;
  5415. } // if: memory allocation failed
  5416. // This call can't fail - the dest buffer is the same size as the src buffer, including the NULL.
  5417. StringCchCopyNW( pszTypeName, cchTypeNameSize, pcszTypeNameIn, cchTypeNameSize );
  5418. m_pgnResTypeGUIDNameMap[ m_idxNextMapEntry ].m_guidTypeGUID = rcguidTypeGuidIn;
  5419. m_pgnResTypeGUIDNameMap[ m_idxNextMapEntry ].m_pszTypeName = pszTypeName;
  5420. ++m_idxNextMapEntry;
  5421. Cleanup:
  5422. HRETURN( hr );
  5423. } //*** CPostCfgManager::HrMapResTypeGUIDToName
  5424. //////////////////////////////////////////////////////////////////////////////
  5425. //++
  5426. //
  5427. // CPostCfgManager::PcszLookupTypeNameByGUID
  5428. //
  5429. // Description:
  5430. // Given a resource type GUID this function finds the resource type name
  5431. // if any.
  5432. //
  5433. // Arguments:
  5434. // rcguidTypeGuidIn
  5435. // Resource type GUID which is to be mapped to a resource type name.
  5436. //
  5437. // Return Values:
  5438. // Pointer to the name of the resource type
  5439. // If the type GUID maps to name
  5440. //
  5441. // NULL
  5442. // If there is no type name associated with the input GUID
  5443. //
  5444. //--
  5445. //////////////////////////////////////////////////////////////////////////////
  5446. const WCHAR *
  5447. CPostCfgManager::PcszLookupTypeNameByGUID(
  5448. const GUID & rcguidTypeGuidIn
  5449. )
  5450. {
  5451. TraceFunc( "" );
  5452. ULONG idxCurrentMapEntry;
  5453. const WCHAR * pcszTypeName = NULL;
  5454. TraceMsgGUID( mtfFUNC, "Trying to look up the the type name of resource type ", rcguidTypeGuidIn );
  5455. for ( idxCurrentMapEntry = 0; idxCurrentMapEntry < m_idxNextMapEntry; ++idxCurrentMapEntry )
  5456. {
  5457. if ( IsEqualGUID( rcguidTypeGuidIn, m_pgnResTypeGUIDNameMap[ idxCurrentMapEntry ].m_guidTypeGUID ) != FALSE )
  5458. {
  5459. // A mapping has been found.
  5460. pcszTypeName = m_pgnResTypeGUIDNameMap[ idxCurrentMapEntry ].m_pszTypeName;
  5461. TraceMsg( mtfFUNC, "The name of the type is '%s'", pcszTypeName );
  5462. break;
  5463. } // if: this GUID has been found in the map
  5464. } // for: iterate through the existing entries in the map
  5465. if ( pcszTypeName == NULL )
  5466. {
  5467. TraceMsg( mtfFUNC, "The input GUID does not map to any resource type name." );
  5468. } // if: this GUID does not exist in the map
  5469. RETURN( pcszTypeName );
  5470. } //*** CPostCfgManager::PcszLookupTypeNameByGUID
  5471. //////////////////////////////////////////////////////////////////////////////
  5472. //
  5473. // HRESULT
  5474. // CPostCfgManager::HrPreInitializeExistingResources
  5475. //
  5476. //////////////////////////////////////////////////////////////////////////////
  5477. HRESULT
  5478. CPostCfgManager::HrPreInitializeExistingResources( void )
  5479. {
  5480. TraceFunc( "" );
  5481. HRESULT hr;
  5482. CResourceEntry * presentry;
  5483. BSTR bstrNotification = NULL;
  5484. BSTR bstrClusterNameResourceName = NULL;
  5485. BSTR bstrClusterIPAddressResourceName = NULL;
  5486. BSTR bstrClusterQuorumResourceName = NULL;
  5487. HRESOURCE hClusterNameResource = NULL;
  5488. HRESOURCE hClusterIPAddressResource = NULL;
  5489. HRESOURCE hClusterQuorumResource = NULL;
  5490. Assert( m_rgpResources == NULL );
  5491. Assert( m_cAllocedResources == 0 );
  5492. Assert( m_cResources == 0 );
  5493. hr = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_TASKID_MINOR_LOCATE_EXISTING_QUORUM_DEVICE, &bstrNotification ) );
  5494. if ( FAILED( hr ) )
  5495. {
  5496. SSR_LOG_ERR(
  5497. TASKID_Major_Client_And_Server_Log
  5498. , TASKID_Minor_HrPreInitializeExistingResources_LoadString_LocateExistingQuorum
  5499. , hr
  5500. , L"Failed the load string for locating existing quorum resource."
  5501. );
  5502. STATUS_REPORT_REF_POSTCFG(
  5503. TASKID_Major_Configure_Resources
  5504. , TASKID_Minor_HrPreInitializeExistingResources_LoadString_LocateExistingQuorum
  5505. , IDS_TASKID_MINOR_ERROR_LOADSTR_QUORUM_RES
  5506. , IDS_REF_MINOR_ERROR_LOADSTR_QUORUM_RES
  5507. , hr
  5508. );
  5509. goto Cleanup;
  5510. }
  5511. m_rgpResources = (CResourceEntry **) TraceAlloc( 0, sizeof(CResourceEntry *) * RESOURCE_INCREMENT );
  5512. if ( m_rgpResources == NULL )
  5513. {
  5514. hr = THR( E_OUTOFMEMORY );
  5515. SSR_LOG_ERR(
  5516. TASKID_Major_Client_And_Server_Log
  5517. , TASKID_Minor_HrPreInitializeExistingResources_OutOfMemory
  5518. , hr
  5519. , L"Out of memory"
  5520. );
  5521. STATUS_REPORT_REF_POSTCFG(
  5522. TASKID_Major_Configure_Resources
  5523. , TASKID_Minor_HrPreInitializeExistingResources_OutOfMemory
  5524. , IDS_TASKID_MINOR_ERROR_OUT_OF_MEMORY
  5525. , IDS_REF_MINOR_ERROR_OUT_OF_MEMORY
  5526. , hr
  5527. );
  5528. } // if:
  5529. for ( ; m_cAllocedResources < RESOURCE_INCREMENT; m_cAllocedResources ++ )
  5530. {
  5531. hr = THR( CResourceEntry::S_HrCreateInstance( &m_rgpResources[ m_cAllocedResources ], m_pcccb, m_lcid ) );
  5532. if ( FAILED( hr ) )
  5533. {
  5534. SSR_LOG_ERR(
  5535. TASKID_Major_Client_And_Server_Log
  5536. , TASKID_Minor_HrPreInitializeExistingResources_CResourceEntry
  5537. , hr
  5538. , L"[PC-Create] Failed to create resource entry object. Aborting."
  5539. );
  5540. STATUS_REPORT_MINOR_REF_POSTCFG(
  5541. TASKID_Major_Configure_Resources
  5542. , IDS_TASKID_MINOR_ERROR_CREATE_RESENTRY
  5543. , IDS_REF_MINOR_ERROR_CREATE_RESENTRY
  5544. , hr
  5545. );
  5546. goto Cleanup;
  5547. }
  5548. } // for:
  5549. Assert( m_cAllocedResources == RESOURCE_INCREMENT );
  5550. //
  5551. // Create default resources such as Cluster IP, Cluster Name resource, and Quorum Device
  5552. //
  5553. Assert( m_cResources == 0 );
  5554. //
  5555. // Get the core resources and their names.
  5556. //
  5557. hr = THR( HrGetCoreClusterResourceNames(
  5558. &bstrClusterNameResourceName
  5559. , &hClusterNameResource
  5560. , &bstrClusterIPAddressResourceName
  5561. , &hClusterIPAddressResource
  5562. , &bstrClusterQuorumResourceName
  5563. , &hClusterQuorumResource
  5564. ) );
  5565. if ( FAILED( hr ) )
  5566. {
  5567. goto Cleanup;
  5568. } // if:
  5569. //
  5570. // Add Cluster IP Address resource
  5571. //
  5572. m_idxIPAddress = m_cResources;
  5573. presentry = m_rgpResources[ m_cResources ];
  5574. // This give ownership of bstrClusterIPAddressResourceName away
  5575. hr = THR( presentry->SetName( bstrClusterIPAddressResourceName ) );
  5576. if ( FAILED( hr ) )
  5577. {
  5578. SSR_LOG_ERR(
  5579. TASKID_Major_Client_And_Server_Log
  5580. , TASKID_Minor_HrPreInitializeExistingResources_IP_SetName
  5581. , hr
  5582. , L"Failed to set 'cluster ip' resource name."
  5583. );
  5584. STATUS_REPORT_REF_POSTCFG1(
  5585. TASKID_Major_Configure_Resources
  5586. , TASKID_Minor_HrPreInitializeExistingResources_IP_SetName
  5587. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_NAME
  5588. , IDS_REF_MINOR_ERROR_SET_RESOURCE_NAME
  5589. , hr
  5590. , bstrClusterIPAddressResourceName
  5591. );
  5592. goto Cleanup;
  5593. }
  5594. bstrClusterIPAddressResourceName = NULL;
  5595. hr = THR( presentry->SetType( &RESTYPE_ClusterIPAddress ) );
  5596. if ( FAILED( hr ) )
  5597. {
  5598. SSR_LOG_ERR(
  5599. TASKID_Major_Client_And_Server_Log
  5600. , TASKID_Minor_HrPreInitializeExistingResources_IP_SetType
  5601. , hr
  5602. , L"Failed to set 'cluster ip' resource type."
  5603. );
  5604. STATUS_REPORT_REF_POSTCFG(
  5605. TASKID_Major_Configure_Resources
  5606. , TASKID_Minor_HrPreInitializeExistingResources_IP_SetType
  5607. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_TYPE
  5608. , IDS_REF_MINOR_ERROR_SET_RESOURCE_TYPE
  5609. , hr
  5610. );
  5611. goto Cleanup;
  5612. }
  5613. hr = THR( presentry->SetClassType( &RESCLASSTYPE_IPAddress ) );
  5614. if ( FAILED( hr ) )
  5615. {
  5616. SSR_LOG_ERR(
  5617. TASKID_Major_Client_And_Server_Log
  5618. , TASKID_Minor_HrPreInitializeExistingResources_IP_SetClassType
  5619. , hr
  5620. , L"Failed to set 'cluster ip' resource class type."
  5621. );
  5622. STATUS_REPORT_REF_POSTCFG(
  5623. TASKID_Major_Configure_Resources
  5624. , TASKID_Minor_HrPreInitializeExistingResources_IP_SetClassType
  5625. , IDS_TASKID_MINOR_ERROR_SET_RESCLASS_TYPE
  5626. , IDS_REF_MINOR_ERROR_SET_RESCLASS_TYPE
  5627. , hr
  5628. );
  5629. goto Cleanup;
  5630. }
  5631. hr = THR( presentry->SetFlags( dfSHARED ) );
  5632. if ( FAILED( hr ) )
  5633. {
  5634. SSR_LOG_ERR(
  5635. TASKID_Major_Client_And_Server_Log
  5636. , TASKID_Minor_HrPreInitializeExistingResources_IP_SetFlags
  5637. , hr
  5638. , L"Failed to set 'cluster ip' resource flags."
  5639. );
  5640. STATUS_REPORT_REF_POSTCFG(
  5641. TASKID_Major_Configure_Resources
  5642. , TASKID_Minor_HrPreInitializeExistingResources_IP_SetFlags
  5643. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_FLAGS
  5644. , IDS_REF_MINOR_ERROR_SET_RESOURCE_FLAGS
  5645. , hr
  5646. );
  5647. goto Cleanup;
  5648. }
  5649. hr = THR( presentry->SetHResource( hClusterIPAddressResource ) );
  5650. if ( FAILED( hr ) )
  5651. {
  5652. SSR_LOG_ERR(
  5653. TASKID_Major_Client_And_Server_Log
  5654. , TASKID_Minor_HrPreInitializeExistingResources_IP_SetHResource
  5655. , hr
  5656. , L"Failed to set 'cluster ip' resource handle."
  5657. );
  5658. STATUS_REPORT_REF_POSTCFG(
  5659. TASKID_Major_Configure_Resources
  5660. , TASKID_Minor_HrPreInitializeExistingResources_IP_SetHResource
  5661. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_HANDLE
  5662. , IDS_REF_MINOR_ERROR_SET_RESOURCE_HANDLE
  5663. , hr
  5664. );
  5665. goto Cleanup;
  5666. }
  5667. hClusterIPAddressResource = NULL;
  5668. m_cResources ++;
  5669. //
  5670. // Add Cluster Name resource
  5671. //
  5672. m_idxClusterName = m_cResources;
  5673. presentry = m_rgpResources[ m_cResources ];
  5674. // This give ownership of bstrClusterNameResourceName away
  5675. hr = THR( presentry->SetName( bstrClusterNameResourceName ) );
  5676. if ( FAILED( hr ) )
  5677. {
  5678. SSR_LOG_ERR(
  5679. TASKID_Major_Client_And_Server_Log
  5680. , TASKID_Minor_HrPreInitializeExistingResources_Name_SetName
  5681. , hr
  5682. , L"Failed to set 'cluster name' resource name."
  5683. );
  5684. STATUS_REPORT_REF_POSTCFG1(
  5685. TASKID_Major_Configure_Resources
  5686. , TASKID_Minor_HrPreInitializeExistingResources_Name_SetName
  5687. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_NAME
  5688. , IDS_REF_MINOR_ERROR_SET_RESOURCE_NAME
  5689. , hr
  5690. , bstrClusterNameResourceName
  5691. );
  5692. goto Cleanup;
  5693. }
  5694. bstrClusterNameResourceName = NULL;
  5695. hr = THR( presentry->SetType( &RESTYPE_ClusterNetName ) );
  5696. if ( FAILED( hr ) )
  5697. {
  5698. SSR_LOG_ERR(
  5699. TASKID_Major_Client_And_Server_Log
  5700. , TASKID_Minor_HrPreInitializeExistingResources_Name_SetType
  5701. , hr
  5702. , L"Failed to set 'cluster name' resource type."
  5703. );
  5704. STATUS_REPORT_REF_POSTCFG(
  5705. TASKID_Major_Configure_Resources
  5706. , TASKID_Minor_HrPreInitializeExistingResources_Name_SetType
  5707. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_TYPE
  5708. , IDS_REF_MINOR_ERROR_SET_RESOURCE_TYPE
  5709. , hr
  5710. );
  5711. goto Cleanup;
  5712. }
  5713. hr = THR( presentry->SetClassType( &RESCLASSTYPE_NetworkName ) );
  5714. if ( FAILED( hr ) )
  5715. {
  5716. SSR_LOG_ERR(
  5717. TASKID_Major_Client_And_Server_Log
  5718. , TASKID_Minor_HrPreInitializeExistingResources_Name_SetClassType
  5719. , hr
  5720. , L"Failed to set 'cluster name' resource class type."
  5721. );
  5722. STATUS_REPORT_REF_POSTCFG(
  5723. TASKID_Major_Configure_Resources
  5724. , TASKID_Minor_HrPreInitializeExistingResources_Name_SetClassType
  5725. , IDS_TASKID_MINOR_ERROR_SET_RESCLASS_TYPE
  5726. , IDS_REF_MINOR_ERROR_SET_RESCLASS_TYPE
  5727. , hr
  5728. );
  5729. goto Cleanup;
  5730. }
  5731. hr = THR( presentry->SetFlags( dfSHARED ) );
  5732. if ( FAILED( hr ) )
  5733. {
  5734. SSR_LOG_ERR(
  5735. TASKID_Major_Client_And_Server_Log
  5736. , TASKID_Minor_HrPreInitializeExistingResources_Name_SetFlags
  5737. , hr
  5738. , L"Failed to set 'cluster name' resource flags."
  5739. );
  5740. STATUS_REPORT_REF_POSTCFG(
  5741. TASKID_Major_Configure_Resources
  5742. , TASKID_Minor_HrPreInitializeExistingResources_Name_SetFlags
  5743. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_FLAGS
  5744. , IDS_REF_MINOR_ERROR_SET_RESOURCE_FLAGS
  5745. , hr
  5746. );
  5747. goto Cleanup;
  5748. }
  5749. // Add the dependency on the IP address.
  5750. hr = THR( presentry->AddTypeDependency( &RESTYPE_ClusterIPAddress, dfSHARED ) );
  5751. if ( FAILED( hr ) )
  5752. {
  5753. SSR_LOG_ERR(
  5754. TASKID_Major_Client_And_Server_Log
  5755. , TASKID_Minor_HrPreInitializeExistingResources_Name_AddTypeDependency
  5756. , hr
  5757. , L"Failed to add type dependency for 'cluster name' resource."
  5758. );
  5759. STATUS_REPORT_REF_POSTCFG(
  5760. TASKID_Major_Configure_Resources
  5761. , TASKID_Minor_HrPreInitializeExistingResources_Name_AddTypeDependency
  5762. , IDS_TASKID_MINOR_ERROR_TYPE_DEPENDENCY
  5763. , IDS_REF_MINOR_ERROR_TYPE_DEPENDENCY
  5764. , hr
  5765. );
  5766. goto Cleanup;
  5767. }
  5768. hr = THR( presentry->SetHResource( hClusterNameResource ) );
  5769. if ( FAILED( hr ) )
  5770. {
  5771. SSR_LOG_ERR(
  5772. TASKID_Major_Client_And_Server_Log
  5773. , TASKID_Minor_HrPreInitializeExistingResources_Name_SetHResource
  5774. , hr
  5775. , L"Failed to set 'cluster name' resource handle."
  5776. );
  5777. STATUS_REPORT_REF_POSTCFG(
  5778. TASKID_Major_Configure_Resources
  5779. , TASKID_Minor_HrPreInitializeExistingResources_Name_SetHResource
  5780. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_HANDLE
  5781. , IDS_REF_MINOR_ERROR_SET_RESOURCE_HANDLE
  5782. , hr
  5783. );
  5784. goto Cleanup;
  5785. }
  5786. hClusterNameResource = NULL;
  5787. m_cResources ++;
  5788. //
  5789. // Add Quorum resource
  5790. //
  5791. //
  5792. // KB: gpease 19-JUN-2000
  5793. // Anything before the quorum device will be considered to be
  5794. // in the Cluster Group.
  5795. //
  5796. m_idxQuorumResource = m_cResources;
  5797. presentry = m_rgpResources[ m_cResources ];
  5798. // This give ownership of bstrClusterQuorumResourceName away
  5799. hr = THR( presentry->SetName( bstrClusterQuorumResourceName ) );
  5800. if ( FAILED( hr ) )
  5801. {
  5802. SSR_LOG_ERR(
  5803. TASKID_Major_Client_And_Server_Log
  5804. , TASKID_Minor_HrPreInitializeExistingResources_Quorum_SetName
  5805. , hr
  5806. , L"Failed to set quorum resource name."
  5807. );
  5808. STATUS_REPORT_REF_POSTCFG1(
  5809. TASKID_Major_Configure_Resources
  5810. , TASKID_Minor_HrPreInitializeExistingResources_Quorum_SetName
  5811. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_NAME
  5812. , IDS_REF_MINOR_ERROR_SET_RESOURCE_NAME
  5813. , hr
  5814. , bstrClusterQuorumResourceName
  5815. );
  5816. goto Cleanup;
  5817. }
  5818. bstrClusterQuorumResourceName = NULL;
  5819. /*
  5820. hr = THR( presentry->SetType( &RESTYPE_ClusterQuorumDisk ) );
  5821. if ( FAILED( hr ) )
  5822. {
  5823. SSR_LOG_ERR(
  5824. TASKID_Major_Client_And_Server_Log
  5825. , TASKID_Minor_HrPreInitializeExistingResources_Quorum_SetType
  5826. , hr
  5827. , L"Failed to set quorum resource type."
  5828. );
  5829. STATUS_REPORT_REF_POSTCFG(
  5830. TASKID_Major_Configure_Resources
  5831. , TASKID_Minor_HrPreInitializeExistingResources_Quorum_SetType
  5832. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_TYPE
  5833. , IDS_REF_MINOR_ERROR_SET_RESOURCE_TYPE
  5834. , hr
  5835. );
  5836. goto Cleanup;
  5837. }
  5838. */
  5839. hr = THR( presentry->SetClassType( &RESCLASSTYPE_StorageDevice ) );
  5840. if ( FAILED( hr ) )
  5841. {
  5842. SSR_LOG_ERR(
  5843. TASKID_Major_Client_And_Server_Log
  5844. , TASKID_Minor_HrPreInitializeExistingResources_Quorum_SetClassType
  5845. , hr
  5846. , L"Failed to set quorum resource class type."
  5847. );
  5848. STATUS_REPORT_REF_POSTCFG(
  5849. TASKID_Major_Configure_Resources
  5850. , TASKID_Minor_HrPreInitializeExistingResources_Quorum_SetClassType
  5851. , IDS_TASKID_MINOR_ERROR_SET_RESCLASS_TYPE
  5852. , IDS_REF_MINOR_ERROR_SET_RESCLASS_TYPE
  5853. , hr
  5854. );
  5855. goto Cleanup;
  5856. }
  5857. hr = THR( presentry->SetFlags( dfSHARED ) );
  5858. if ( FAILED( hr ) )
  5859. {
  5860. SSR_LOG_ERR(
  5861. TASKID_Major_Client_And_Server_Log
  5862. , TASKID_Minor_HrPreInitializeExistingResources_Quorum_SetFlags
  5863. , hr
  5864. , L"Failed to set quorum resource flags."
  5865. );
  5866. STATUS_REPORT_REF_POSTCFG(
  5867. TASKID_Major_Configure_Resources
  5868. , TASKID_Minor_HrPreInitializeExistingResources_Quorum_SetFlags
  5869. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_FLAGS
  5870. , IDS_REF_MINOR_ERROR_SET_RESOURCE_FLAGS
  5871. , hr
  5872. );
  5873. goto Cleanup;
  5874. }
  5875. hr = THR( presentry->SetHResource( hClusterQuorumResource ) );
  5876. if ( FAILED( hr ) )
  5877. {
  5878. SSR_LOG_ERR(
  5879. TASKID_Major_Client_And_Server_Log
  5880. , TASKID_Minor_HrPreInitializeExistingResources_Quorum_SetHResource
  5881. , hr
  5882. , L"Failed to set quorum resource handle."
  5883. );
  5884. STATUS_REPORT_REF_POSTCFG(
  5885. TASKID_Major_Configure_Resources
  5886. , TASKID_Minor_HrPreInitializeExistingResources_Quorum_SetHResource
  5887. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_HANDLE
  5888. , IDS_REF_MINOR_ERROR_SET_RESOURCE_HANDLE
  5889. , hr
  5890. );
  5891. goto Cleanup;
  5892. }
  5893. hClusterQuorumResource = NULL;
  5894. m_cResources ++;
  5895. //
  5896. // Make sure that the default resource allocation can hold all the
  5897. // default resources.
  5898. //
  5899. AssertMsg( m_cResources <= m_cAllocedResources, "Default resource allocation needs to be bigger!" );
  5900. goto Cleanup;
  5901. Cleanup:
  5902. //
  5903. // Send a status that we found the quorum device.
  5904. //
  5905. hr = THR( SendStatusReport( NULL,
  5906. TASKID_Major_Configure_Resources,
  5907. TASKID_Minor_Locate_Existing_Quorum_Device,
  5908. 10,
  5909. 10,
  5910. 10,
  5911. hr,
  5912. bstrNotification,
  5913. NULL,
  5914. NULL
  5915. ) );
  5916. if ( hr == E_ABORT )
  5917. goto Cleanup;
  5918. // ignore failure
  5919. TraceSysFreeString( bstrNotification );
  5920. TraceSysFreeString( bstrClusterNameResourceName );
  5921. TraceSysFreeString( bstrClusterIPAddressResourceName );
  5922. TraceSysFreeString( bstrClusterQuorumResourceName );
  5923. if ( hClusterNameResource != NULL )
  5924. {
  5925. CloseClusterResource( hClusterNameResource );
  5926. } // if:
  5927. if ( hClusterIPAddressResource != NULL )
  5928. {
  5929. CloseClusterResource( hClusterIPAddressResource );
  5930. } // if:
  5931. if ( hClusterQuorumResource != NULL )
  5932. {
  5933. CloseClusterResource( hClusterQuorumResource );
  5934. } // if:
  5935. HRETURN( hr );
  5936. } //*** CPostCfgManager::HrPreInitializeExistingResources
  5937. //////////////////////////////////////////////////////////////////////////////
  5938. //
  5939. // HRESULT
  5940. // CPostCfgManager::HrAddSpecialResource(
  5941. // BSTR bstrNameIn,
  5942. // const CLSID * pclsidTypeIn,
  5943. // const CLSID * pclsidClassTypeIn
  5944. // )
  5945. //
  5946. //////////////////////////////////////////////////////////////////////////////
  5947. HRESULT
  5948. CPostCfgManager::HrAddSpecialResource(
  5949. BSTR bstrNameIn,
  5950. const CLSID * pclsidTypeIn,
  5951. const CLSID * pclsidClassTypeIn
  5952. )
  5953. {
  5954. TraceFunc( "" );
  5955. HRESULT hr;
  5956. CResourceEntry * presentry;
  5957. //
  5958. // Grow the resource list if nessecary.
  5959. //
  5960. if ( m_cResources == m_cAllocedResources )
  5961. {
  5962. ULONG idxNewCount = m_cAllocedResources + RESOURCE_INCREMENT;
  5963. CResourceEntry ** pnewList;
  5964. pnewList = (CResourceEntry **) TraceAlloc( 0, sizeof( CResourceEntry * ) * idxNewCount );
  5965. if ( pnewList == NULL )
  5966. {
  5967. hr = THR( E_OUTOFMEMORY );
  5968. SSR_LOG_ERR(
  5969. TASKID_Major_Client_And_Server_Log
  5970. , TASKID_Minor_HrAddSpecialResource_OutOfMemory
  5971. , hr
  5972. , L"Out of memory"
  5973. );
  5974. STATUS_REPORT_REF_POSTCFG(
  5975. TASKID_Major_Configure_Resources
  5976. , TASKID_Minor_HrAddSpecialResource_OutOfMemory
  5977. , IDS_TASKID_MINOR_ERROR_OUT_OF_MEMORY
  5978. , IDS_REF_MINOR_ERROR_OUT_OF_MEMORY
  5979. , hr
  5980. );
  5981. goto Cleanup;
  5982. }
  5983. CopyMemory( pnewList, m_rgpResources, sizeof(CResourceEntry *) * m_cAllocedResources );
  5984. TraceFree( m_rgpResources );
  5985. m_rgpResources = pnewList;
  5986. for ( ; m_cAllocedResources < idxNewCount ; m_cAllocedResources ++ )
  5987. {
  5988. hr = THR( CResourceEntry::S_HrCreateInstance( &m_rgpResources[ m_cAllocedResources ], m_pcccb, m_lcid ) );
  5989. if ( FAILED( hr ) )
  5990. {
  5991. SSR_LOG_ERR(
  5992. TASKID_Major_Client_And_Server_Log
  5993. , TASKID_Minor_HrAddSpecialResource_CResourceEntry
  5994. , hr
  5995. , L"[PC-Create] Failed to create resource entry object. Aborting."
  5996. );
  5997. STATUS_REPORT_MINOR_REF_POSTCFG(
  5998. TASKID_Major_Configure_Resources
  5999. , IDS_TASKID_MINOR_ERROR_CREATE_RESENTRY
  6000. , IDS_REF_MINOR_ERROR_CREATE_RESENTRY
  6001. , hr
  6002. );
  6003. goto Cleanup;
  6004. }
  6005. }
  6006. }
  6007. presentry = m_rgpResources[ m_cResources ];
  6008. //
  6009. // Setup the new entry.
  6010. //
  6011. hr = THR( presentry->SetName( bstrNameIn ) );
  6012. if ( FAILED( hr ) )
  6013. {
  6014. SSR_LOG_ERR(
  6015. TASKID_Major_Client_And_Server_Log
  6016. , TASKID_Minor_HrAddSpecialResource_SetName
  6017. , hr
  6018. , L"Failed to set special resource name."
  6019. );
  6020. STATUS_REPORT_REF_POSTCFG1(
  6021. TASKID_Major_Configure_Resources
  6022. , TASKID_Minor_HrAddSpecialResource_SetName
  6023. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_NAME
  6024. , IDS_REF_MINOR_ERROR_SET_RESOURCE_NAME
  6025. , hr
  6026. , bstrNameIn
  6027. );
  6028. goto Cleanup;
  6029. }
  6030. hr = THR( presentry->SetType( pclsidTypeIn ) );
  6031. if ( FAILED( hr ) )
  6032. {
  6033. SSR_LOG_ERR(
  6034. TASKID_Major_Client_And_Server_Log
  6035. , TASKID_Minor_HrAddSpecialResource_SetType
  6036. , hr
  6037. , L"Failed to set special resource type."
  6038. );
  6039. STATUS_REPORT_REF_POSTCFG(
  6040. TASKID_Major_Configure_Resources
  6041. , TASKID_Minor_HrAddSpecialResource_SetType
  6042. , IDS_TASKID_MINOR_ERROR_SET_RESOURCE_TYPE
  6043. , IDS_REF_MINOR_ERROR_SET_RESOURCE_TYPE
  6044. , hr
  6045. );
  6046. goto Cleanup;
  6047. }
  6048. hr = THR( presentry->SetClassType( pclsidClassTypeIn ) );
  6049. if ( FAILED( hr ) )
  6050. {
  6051. SSR_LOG_ERR(
  6052. TASKID_Major_Client_And_Server_Log
  6053. , TASKID_Minor_HrAddSpecialResource_SetClassType
  6054. , hr
  6055. , L"Failed to set special resource class type."
  6056. );
  6057. STATUS_REPORT_REF_POSTCFG(
  6058. TASKID_Major_Configure_Resources
  6059. , TASKID_Minor_HrAddSpecialResource_SetClassType
  6060. , IDS_TASKID_MINOR_ERROR_SET_RESCLASS_TYPE
  6061. , IDS_REF_MINOR_ERROR_SET_RESCLASS_TYPE
  6062. , hr
  6063. );
  6064. goto Cleanup;
  6065. }
  6066. m_cResources ++;
  6067. Cleanup:
  6068. HRETURN( hr );
  6069. } //*** CPostCfgManager::HrAddSpecialResource
  6070. //////////////////////////////////////////////////////////////////////////////
  6071. //
  6072. // HRESULT
  6073. // CPostCfgManager::HrCreateResourceInstance(
  6074. // ULONG idxResourceIn,
  6075. // HGROUP hGroupIn,
  6076. // LPCWSTR pszResTypeIn,
  6077. // HRESOURCE * phResourceOut
  6078. // )
  6079. //
  6080. //////////////////////////////////////////////////////////////////////////////
  6081. HRESULT
  6082. CPostCfgManager::HrCreateResourceInstance(
  6083. ULONG idxResourceIn,
  6084. HGROUP hGroupIn,
  6085. LPCWSTR pszResTypeIn,
  6086. HRESOURCE * phResourceOut
  6087. )
  6088. {
  6089. TraceFunc3( "idxResourceIn = %u, hGroupIn = %p, pszResTypeIn = '%ws'",
  6090. idxResourceIn, hGroupIn, pszResTypeIn );
  6091. HRESULT hr;
  6092. DWORD dw;
  6093. BSTR bstrName; // don't free
  6094. CResourceEntry * presentry;
  6095. BSTR bstrNotification = NULL;
  6096. Assert( phResourceOut != NULL );
  6097. Assert( idxResourceIn < m_cResources );
  6098. Assert( hGroupIn != NULL );
  6099. presentry = m_rgpResources[ idxResourceIn ];
  6100. hr = THR( presentry->GetName( &bstrName ) );
  6101. if ( FAILED( hr ) )
  6102. {
  6103. SSR_LOG_ERR(
  6104. TASKID_Major_Client_And_Server_Log
  6105. , TASKID_Minor_HrCreateResourceInstance_GetName
  6106. , hr
  6107. , L"Failed to get resource instance name."
  6108. );
  6109. STATUS_REPORT_REF_POSTCFG(
  6110. TASKID_Major_Configure_Resources
  6111. , TASKID_Minor_HrCreateResourceInstance_GetName
  6112. , IDS_TASKID_MINOR_ERROR_GET_RESOURCE_NAME
  6113. , IDS_REF_MINOR_ERROR_GET_RESOURCE_NAME
  6114. , hr
  6115. );
  6116. goto Cleanup;
  6117. }
  6118. //
  6119. // Tell the UI what we are doing.
  6120. //
  6121. hr = THR( SendStatusReport(
  6122. NULL
  6123. , TASKID_Major_Configure_Resources
  6124. , TASKID_Minor_Creating_Resource
  6125. , 0
  6126. , m_cResources
  6127. , idxResourceIn
  6128. , S_OK
  6129. , NULL
  6130. , NULL
  6131. , NULL
  6132. ) );
  6133. if ( hr == E_ABORT )
  6134. {
  6135. goto Cleanup;
  6136. }
  6137. //
  6138. // See if the resource already exists. We need to do this because the user
  6139. // might have clicked "Retry" in the UI. We don't want to create another
  6140. // instance of existing resources.
  6141. //
  6142. *phResourceOut = OpenClusterResource( m_hCluster, bstrName );
  6143. if ( *phResourceOut == NULL )
  6144. {
  6145. //
  6146. // Create a new resource instance.
  6147. //
  6148. *phResourceOut = CreateClusterResource( hGroupIn, bstrName, pszResTypeIn, 0 );
  6149. if ( *phResourceOut == NULL )
  6150. {
  6151. hr = HRESULT_FROM_WIN32( TW32( GetLastError() ) );
  6152. SSR_LOG1(
  6153. TASKID_Major_Client_And_Server_Log
  6154. , TASKID_Minor_HrCreateResourceInstance_CreateClusterResource
  6155. , hr
  6156. , L"[PC-Create] %1!ws!: CreateClusterResource failed. Its dependents may not be created. Skipping."
  6157. , bstrNotification
  6158. , bstrName
  6159. );
  6160. STATUS_REPORT_REF_POSTCFG1(
  6161. TASKID_Major_Configure_Resources
  6162. , TASKID_Minor_HrCreateResourceInstance_CreateClusterResource
  6163. , IDS_TASKID_MINOR_ERROR_CREATE_RESOURCE
  6164. , IDS_REF_MINOR_ERROR_CREATE_RESOURCE
  6165. , hr
  6166. , bstrName
  6167. );
  6168. goto Cleanup;
  6169. } // if: failure
  6170. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  6171. TASKID_Minor_HrCreateResourceInstance_CreateClusterResource_Successful,
  6172. hr,
  6173. L"[PC-Create] %1!ws!: Resource created successfully.",
  6174. bstrNotification,
  6175. bstrName
  6176. );
  6177. }
  6178. else
  6179. {
  6180. SSR_LOG1( TASKID_Major_Client_And_Server_Log,
  6181. TASKID_Minor_HrCreateResourceInstance_FoundExistingResource,
  6182. hr,
  6183. L"[PC-Create] %1!ws!: Found existing resource.",
  6184. bstrNotification,
  6185. bstrName
  6186. );
  6187. //
  6188. // Make sure the resource is in the group we think it is.
  6189. //
  6190. // don't wrap - this can fail with ERROR_ALREADY_EXISTS.
  6191. dw = ChangeClusterResourceGroup( *phResourceOut, hGroupIn );
  6192. if ( dw == ERROR_ALREADY_EXISTS )
  6193. {
  6194. // no-op. It's the way we want it.
  6195. }
  6196. else if ( dw != ERROR_SUCCESS )
  6197. {
  6198. hr = HRESULT_FROM_WIN32( dw );
  6199. SSR_LOG1(
  6200. TASKID_Major_Client_And_Server_Log
  6201. , TASKID_Minor_HrCreateResourceInstance_ChangeClusterResourceGroup
  6202. , hr
  6203. , L"[PC-Create] %1!ws!: Can't move existing resource to proper group. Configuration may not work."
  6204. , bstrNotification
  6205. , bstrName
  6206. );
  6207. STATUS_REPORT_REF_POSTCFG1(
  6208. TASKID_Major_Configure_Resources
  6209. , TASKID_Minor_HrCreateResourceInstance_ChangeClusterResourceGroup
  6210. , IDS_TASKID_MINOR_ERROR_MOVE_RESOURCE
  6211. , IDS_REF_MINOR_ERROR_MOVE_RESOURCE
  6212. , hr
  6213. , bstrName
  6214. );
  6215. }
  6216. }
  6217. //
  6218. // Store off the resource handle.
  6219. //
  6220. hr = THR( presentry->SetHResource( *phResourceOut ) );
  6221. if ( FAILED( hr ) )
  6222. {
  6223. SSR_LOG_ERR(
  6224. TASKID_Major_Client_And_Server_Log
  6225. , TASKID_Minor_HrCreateResourceInstance_SetHResource
  6226. , hr
  6227. , L"Failed to get resource instance handle."
  6228. );
  6229. STATUS_REPORT_REF_POSTCFG1(
  6230. TASKID_Major_Configure_Resources
  6231. , TASKID_Minor_HrCreateResourceInstance_SetHResource
  6232. , IDS_TASKID_MINOR_ERROR_GET_RESOURCE_HANDLE
  6233. , IDS_REF_MINOR_ERROR_GET_RESOURCE_HANDLE
  6234. , hr
  6235. , bstrName
  6236. );
  6237. goto Cleanup;
  6238. }
  6239. //
  6240. // Configure resource.
  6241. //
  6242. hr = THR( presentry->Configure() );
  6243. if ( FAILED( hr ) )
  6244. {
  6245. SSR_LOG_ERR(
  6246. TASKID_Major_Client_And_Server_Log
  6247. , TASKID_Minor_HrCreateResourceInstance_Configure
  6248. , hr
  6249. , L"Failed to configure resource instance."
  6250. );
  6251. // ignore the error and continue.
  6252. }
  6253. //
  6254. // Make a message using the name.
  6255. //
  6256. hr = THR( HrFormatMessageIntoBSTR( g_hInstance,
  6257. IDS_TASKID_MINOR_CREATING_RESOURCE,
  6258. &bstrNotification,
  6259. bstrName
  6260. ) );
  6261. if ( FAILED( hr ) )
  6262. {
  6263. SSR_LOG_ERR(
  6264. TASKID_Major_Client_And_Server_Log
  6265. , TASKID_Minor_HrCreateResourceInstance_LoadString_CreatingResource
  6266. , hr
  6267. , L"Failed to format message for creating resource."
  6268. );
  6269. goto Cleanup;
  6270. }
  6271. //
  6272. // Tell the UI what we are doing.
  6273. //
  6274. hr = THR( SendStatusReport( NULL,
  6275. TASKID_Major_Client_And_Server_Log, // informative only
  6276. TASKID_Minor_Creating_Resource,
  6277. 0,
  6278. 2,
  6279. 2,
  6280. hr, // log the error on the client side
  6281. bstrNotification,
  6282. NULL,
  6283. NULL
  6284. ) );
  6285. if ( hr == E_ABORT )
  6286. {
  6287. goto Cleanup;
  6288. }
  6289. // ignore failure
  6290. //
  6291. // TODO: gpease 24-AUG-2000
  6292. // What to do if we have a failure?? For now I think we should keep going!
  6293. //
  6294. hr = S_OK;
  6295. Cleanup:
  6296. TraceSysFreeString( bstrNotification );
  6297. HRETURN( hr );
  6298. } //*** CPostCfgManager::HrCreateResourceInstance
  6299. //////////////////////////////////////////////////////////////////////////////
  6300. //
  6301. // CPostCfgManager::S_ScDeleteLocalQuorumResource
  6302. //
  6303. //////////////////////////////////////////////////////////////////////////////
  6304. DWORD
  6305. CPostCfgManager::S_ScDeleteLocalQuorumResource(
  6306. HCLUSTER hClusterIn
  6307. , HRESOURCE hSelfIn
  6308. , HRESOURCE hLQuorumIn
  6309. , PVOID pvParamIn
  6310. )
  6311. {
  6312. TraceFunc( "" );
  6313. DWORD sc = ERROR_SUCCESS;
  6314. signed long slOfflineTimeOut = 60; // seconds
  6315. CLUSTER_RESOURCE_STATE crs;
  6316. HCHANGE hc = reinterpret_cast< HCHANGE >( INVALID_HANDLE_VALUE );
  6317. CPostCfgManager * pcpcmThis = reinterpret_cast< CPostCfgManager * >( pvParamIn );
  6318. DWORD dwStatusCurrent = 0;
  6319. HRESULT hr;
  6320. //
  6321. // Check if the this pointer is valid.
  6322. //
  6323. if ( pvParamIn == NULL )
  6324. {
  6325. // If the pointer is invalid, set it to a valid address and continue.
  6326. hr = HRESULT_FROM_WIN32( TW32( ERROR_INVALID_PARAMETER ) );
  6327. LogMsg( "[PC] Error: An invalid parameter was received while trying to delete the Local Quorum resource." );
  6328. STATUS_REPORT_PTR_POSTCFG(
  6329. pcpcmThis
  6330. , TASKID_Major_Configure_Resources
  6331. , TASKID_Minor_CPostCfgManager_S_ScDeleteLocalQuorumResource_InvalidParam
  6332. , IDS_TASKID_MINOR_ERROR_INVALID_PARAM
  6333. , hr
  6334. );
  6335. goto Cleanup;
  6336. }
  6337. // Get the state of the resource.
  6338. crs = GetClusterResourceState( hLQuorumIn, NULL, NULL, NULL, NULL );
  6339. // Check if it is offline - if it is, then we can proceed to deleting it.
  6340. if ( crs == ClusterResourceOffline )
  6341. {
  6342. TraceFlow( "The Local Quorum resource is already offline." );
  6343. goto Cleanup;
  6344. }
  6345. TraceFlow( "Trying to take the Local Quorum resource offline." );
  6346. // If we are here, the resource is not yet offline. Instruct it to go offline.
  6347. sc = OfflineClusterResource( hLQuorumIn );
  6348. if ( ( sc != ERROR_SUCCESS ) && ( sc != ERROR_IO_PENDING ) )
  6349. {
  6350. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  6351. LogMsg( "[PC] Error %#08x occurred trying to take the Local Quorum resource offline.", sc );
  6352. STATUS_REPORT_PTR_POSTCFG(
  6353. pcpcmThis
  6354. , TASKID_Major_Configure_Resources
  6355. , TASKID_Minor_CPostCfgManager_S_ScDeleteLocalQuorumResource_OfflineQuorum
  6356. , IDS_TASKID_MINOR_ERROR_OFFLINE_QUORUM
  6357. , hr
  6358. );
  6359. goto Cleanup;
  6360. } // if: an error occurred trying to take the resource offline
  6361. if ( sc == ERROR_IO_PENDING )
  6362. {
  6363. TraceFlow1( "Waiting %d seconds for the Local Quorum resource to go offline.", slOfflineTimeOut );
  6364. // Create a notification port for resource state changes
  6365. hc = CreateClusterNotifyPort(
  6366. reinterpret_cast< HCHANGE >( INVALID_HANDLE_VALUE )
  6367. , hClusterIn
  6368. , CLUSTER_CHANGE_RESOURCE_STATE
  6369. , NULL
  6370. );
  6371. if ( hc == NULL )
  6372. {
  6373. sc = TW32( GetLastError() );
  6374. hr = HRESULT_FROM_WIN32( sc );
  6375. LogMsg( "[PC] Error %#08x occurred trying to create a cluster notification port.", hr );
  6376. STATUS_REPORT_PTR_POSTCFG(
  6377. pcpcmThis
  6378. , TASKID_Major_Configure_Resources
  6379. , TASKID_Minor_CPostCfgManager_S_ScDeleteLocalQuorumResource_NotifPort
  6380. , IDS_TASKID_MINOR_ERROR_NOTIFICATION_PORT
  6381. , hr
  6382. );
  6383. goto Cleanup;
  6384. } // if: we could not create a notification port
  6385. sc = TW32( RegisterClusterNotify( hc, CLUSTER_CHANGE_RESOURCE_STATE, hLQuorumIn, NULL ) );
  6386. if ( sc != ERROR_SUCCESS )
  6387. {
  6388. hr = HRESULT_FROM_WIN32( sc );
  6389. LogMsg( "[PC] Error %#08x occurred trying to register for cluster notifications.", hr );
  6390. STATUS_REPORT_PTR_POSTCFG(
  6391. pcpcmThis
  6392. , TASKID_Major_Configure_Resources
  6393. , TASKID_Minor_CPostCfgManager_S_ScDeleteLocalQuorumResource_RegNotification
  6394. , IDS_TASKID_MINOR_ERROR_REGISTER_NOTIFICATION
  6395. , hr
  6396. );
  6397. goto Cleanup;
  6398. } // if:
  6399. // Change the status report range.
  6400. dwStatusCurrent = 0;
  6401. // Wait for slOfflineTimeOut seconds for the resource to go offline.
  6402. for ( ; slOfflineTimeOut > 0; --slOfflineTimeOut )
  6403. {
  6404. DWORD dwFilterType;
  6405. crs = GetClusterResourceState( hLQuorumIn, NULL, NULL, NULL, NULL );
  6406. if ( crs == ClusterResourceOffline )
  6407. {
  6408. TraceFlow1( "The local quorum resource has gone offline with %d seconds to spare.", slOfflineTimeOut );
  6409. break;
  6410. } // if: the resource is now offline
  6411. sc = GetClusterNotify( hc, NULL, &dwFilterType, NULL, NULL, 1000 ); // wait for one second
  6412. if ( ( sc != ERROR_SUCCESS ) && ( sc != WAIT_TIMEOUT ) )
  6413. {
  6414. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  6415. LogMsg( "[PC] Error %#08x occurred trying wait for a resource state change notification.", hr );
  6416. STATUS_REPORT_PTR_POSTCFG(
  6417. pcpcmThis
  6418. , TASKID_Major_Configure_Resources
  6419. , TASKID_Minor_CPostCfgManager_S_ScDeleteLocalQuorumResource_TimeOut
  6420. , IDS_TASKID_MINOR_ERROR_STATE_CHANGE_TIMEOUT
  6421. , hr
  6422. );
  6423. goto Cleanup;
  6424. } // if: something went wrong
  6425. // Reset sc, since it could be WAIT_TIMEOUT here
  6426. sc = ERROR_SUCCESS;
  6427. Assert( dwFilterType == CLUSTER_CHANGE_RESOURCE_STATE );
  6428. // Send a status report that we are deleting the quorum device.
  6429. ++dwStatusCurrent;
  6430. THR(
  6431. pcpcmThis->SendStatusReport(
  6432. NULL
  6433. , TASKID_Major_Configure_Resources
  6434. , TASKID_Minor_Delete_LocalQuorum
  6435. , 0
  6436. , pcpcmThis->m_dwLocalQuorumStatusMax
  6437. , dwStatusCurrent
  6438. , HRESULT_FROM_WIN32( sc )
  6439. , NULL // don't update text
  6440. , NULL
  6441. , NULL
  6442. )
  6443. );
  6444. } // for: loop while the timeout has not expired
  6445. } // if:
  6446. else
  6447. {
  6448. crs = ClusterResourceOffline; // the resource went offline immediately.
  6449. } // else:
  6450. //
  6451. // If we are here, then one of two things could have happened:
  6452. // 1. The resource has gone offline
  6453. // 2. The timeout has expired
  6454. // Check to see which of the above is true.
  6455. //
  6456. if ( crs != ClusterResourceOffline )
  6457. {
  6458. // We cannot be here if the timeout has not expired.
  6459. Assert( slOfflineTimeOut <= 0 );
  6460. LogMsg( "[PC] Error: The Local Quorum resource could not be taken offline." );
  6461. sc = TW32( WAIT_TIMEOUT );
  6462. hr = HRESULT_FROM_WIN32( sc );
  6463. STATUS_REPORT_PTR_POSTCFG(
  6464. pcpcmThis
  6465. , TASKID_Major_Configure_Resources
  6466. , TASKID_Minor_CPostCfgManager_S_ScDeleteLocalQuorumResource_OfflineQuorum2
  6467. , IDS_TASKID_MINOR_ERROR_OFFLINE_QUORUM
  6468. , hr
  6469. );
  6470. goto Cleanup;
  6471. } // if: the timeout has expired
  6472. // If we are here, the resource is offline.
  6473. TraceFlow( "The Local Quorum resource is offline." );
  6474. if ( pcpcmThis != NULL )
  6475. {
  6476. // Send a status report that we are deleting the quorum device.
  6477. ++dwStatusCurrent;
  6478. THR(
  6479. pcpcmThis->SendStatusReport(
  6480. NULL
  6481. , TASKID_Major_Configure_Resources
  6482. , TASKID_Minor_Delete_LocalQuorum
  6483. , 0
  6484. , pcpcmThis->m_dwLocalQuorumStatusMax
  6485. , dwStatusCurrent
  6486. , HRESULT_FROM_WIN32( sc )
  6487. , NULL // don't update text
  6488. , NULL
  6489. , NULL
  6490. )
  6491. );
  6492. } // if: the this pointer is valid
  6493. // If we are here, the resource is offline - now delete it.
  6494. sc = TW32( DeleteClusterResource( hLQuorumIn ) );
  6495. if ( sc != ERROR_SUCCESS )
  6496. {
  6497. hr = HRESULT_FROM_WIN32( sc );
  6498. LogMsg( "[PC] Error %#08x occurred trying to delete the Local Quorum resource.", hr );
  6499. STATUS_REPORT_PTR_POSTCFG(
  6500. pcpcmThis
  6501. , TASKID_Major_Configure_Resources
  6502. , TASKID_Minor_CPostCfgManager_S_ScDeleteLocalQuorumResource_DeleteQuorum
  6503. , IDS_TASKID_MINOR_ERROR_DELETE_QUORUM
  6504. , hr
  6505. );
  6506. } // if: we could not delete the resource
  6507. else
  6508. {
  6509. LogMsg( "[PC] The Local Quorum resource has been deleted." );
  6510. } // else: the resource has been deleted
  6511. // Send a status report that we are deleting the quorum device.
  6512. ++dwStatusCurrent;
  6513. THR(
  6514. pcpcmThis->SendStatusReport(
  6515. NULL
  6516. , TASKID_Major_Configure_Resources
  6517. , TASKID_Minor_Delete_LocalQuorum
  6518. , 0
  6519. , pcpcmThis->m_dwLocalQuorumStatusMax
  6520. , dwStatusCurrent
  6521. , HRESULT_FROM_WIN32( sc )
  6522. , NULL // don't update text
  6523. , NULL
  6524. , NULL
  6525. )
  6526. );
  6527. Cleanup:
  6528. //
  6529. // Cleanup
  6530. //
  6531. if ( hc != INVALID_HANDLE_VALUE )
  6532. {
  6533. CloseClusterNotifyPort( hc );
  6534. } // if: we had created a cluster notification port
  6535. W32RETURN( sc );
  6536. } //*** CPostCfgManager::S_ScDeleteLocalQuorumResource
  6537. //////////////////////////////////////////////////////////////////////////////
  6538. //
  6539. // HRESULT
  6540. // CPostCfgManager::HrGetCoreClusterResourceNames(
  6541. // BSTR * pbstrClusterNameResourceOut
  6542. // , BSTR * pbstrClusterIPAddressNameOut
  6543. // , BSTR * pbstrClusterQuorumResourceNameOut
  6544. // )
  6545. //
  6546. //////////////////////////////////////////////////////////////////////////////
  6547. HRESULT
  6548. CPostCfgManager::HrGetCoreClusterResourceNames(
  6549. BSTR * pbstrClusterNameResourceNameOut
  6550. , HRESOURCE * phClusterNameResourceOut
  6551. , BSTR * pbstrClusterIPAddressNameOut
  6552. , HRESOURCE * phClusterIPAddressResourceOut
  6553. , BSTR * pbstrClusterQuorumResourceNameOut
  6554. , HRESOURCE * phClusterQuorumResourceOut
  6555. )
  6556. {
  6557. TraceFunc( "" );
  6558. Assert( m_hCluster != NULL );
  6559. Assert( pbstrClusterNameResourceNameOut != NULL );
  6560. Assert( phClusterNameResourceOut != NULL );
  6561. Assert( pbstrClusterIPAddressNameOut != NULL );
  6562. Assert( phClusterIPAddressResourceOut != NULL );
  6563. Assert( pbstrClusterQuorumResourceNameOut != NULL );
  6564. Assert( phClusterQuorumResourceOut != NULL );
  6565. HRESULT hr = S_OK;
  6566. WCHAR * pszName = NULL;
  6567. DWORD cchName = 33;
  6568. DWORD cch;
  6569. HRESOURCE hClusterIPAddressResource = NULL;
  6570. HRESOURCE hClusterNameResource = NULL;
  6571. HRESOURCE hClusterQuorumResource = NULL;
  6572. DWORD sc;
  6573. BSTR * pbstr = NULL;
  6574. HRESOURCE hResource = NULL;
  6575. int idx;
  6576. sc = TW32( ResUtilGetCoreClusterResources( m_hCluster, &hClusterNameResource, &hClusterIPAddressResource, &hClusterQuorumResource ) );
  6577. if ( sc != ERROR_SUCCESS )
  6578. {
  6579. hr = HRESULT_FROM_WIN32( sc );
  6580. LogMsg( L"[PC] Error getting core resources. (hr = %#08x)", hr );
  6581. goto Cleanup;
  6582. } // if:
  6583. Assert( hClusterNameResource != NULL );
  6584. Assert( hClusterIPAddressResource != NULL );
  6585. Assert( hClusterQuorumResource != NULL );
  6586. pszName = new WCHAR[ cchName ];
  6587. if ( pszName == NULL )
  6588. {
  6589. hr = THR( E_OUTOFMEMORY );
  6590. goto Cleanup;
  6591. } // if:
  6592. for ( idx = 0; idx < 3; )
  6593. {
  6594. switch ( idx )
  6595. {
  6596. case 0:
  6597. {
  6598. hResource = hClusterNameResource;
  6599. pbstr = pbstrClusterNameResourceNameOut;
  6600. break;
  6601. } // case:
  6602. case 1:
  6603. {
  6604. hResource = hClusterIPAddressResource;
  6605. pbstr = pbstrClusterIPAddressNameOut;
  6606. break;
  6607. } // case:
  6608. case 2:
  6609. {
  6610. hResource = hClusterQuorumResource;
  6611. pbstr = pbstrClusterQuorumResourceNameOut;
  6612. break;
  6613. } // case:
  6614. } // switch:
  6615. //
  6616. // Reset cch to be the allocated value...
  6617. //
  6618. cch = cchName;
  6619. sc = ResUtilGetResourceName( hResource, pszName, &cch );
  6620. if ( sc == ERROR_MORE_DATA )
  6621. {
  6622. delete [] pszName;
  6623. pszName = NULL;
  6624. cch++;
  6625. cchName = cch;
  6626. pszName = new WCHAR[ cchName ];
  6627. if ( pszName == NULL )
  6628. {
  6629. hr = THR( E_OUTOFMEMORY );
  6630. goto Cleanup;
  6631. } // if:
  6632. sc = ResUtilGetResourceName( hResource, pszName, &cch );
  6633. } // if:
  6634. if ( sc == ERROR_SUCCESS )
  6635. {
  6636. *pbstr = TraceSysAllocString( pszName );
  6637. if ( *pbstr == NULL )
  6638. {
  6639. hr = THR( E_OUTOFMEMORY );
  6640. goto Cleanup;
  6641. } // if:
  6642. pbstr = NULL;
  6643. hr = S_OK;
  6644. idx++;
  6645. continue;
  6646. } // if: ERROR_SUCCESS
  6647. else
  6648. {
  6649. hr = HRESULT_FROM_WIN32( TW32( sc ) );
  6650. SSR_LOG_ERR(
  6651. TASKID_Major_Client_And_Server_Log
  6652. , TASKID_Minor_HrGetCoreClusterResourceNames_GetResourceName
  6653. , hr
  6654. , L"Failed to get a resource name."
  6655. );
  6656. STATUS_REPORT_REF_POSTCFG(
  6657. TASKID_Major_Configure_Resources
  6658. , TASKID_Minor_HrGetCoreClusterResourceNames_GetResourceName
  6659. , IDS_TASKID_MINOR_ERROR_GET_RESOURCE_NAME
  6660. , IDS_REF_MINOR_ERROR_GET_RESOURCE_NAME
  6661. , hr
  6662. );
  6663. switch ( idx )
  6664. {
  6665. case 0:
  6666. {
  6667. LogMsg( L"[PC] Error getting the name of the cluster name resource. (hr = %#08x)", hr );
  6668. break;
  6669. } // case:
  6670. case 1:
  6671. {
  6672. LogMsg( L"[PC] Error getting the name of the cluster IP address resource. (hr = %#08x)", hr );
  6673. break;
  6674. } // case:
  6675. case 2:
  6676. {
  6677. LogMsg( L"[PC] Error getting the name of the cluster quorum resource. (hr = %#08x)", hr );
  6678. break;
  6679. } // case:
  6680. } // switch:
  6681. goto Cleanup;
  6682. } // else: sc != ERROR_SUCCESS
  6683. } // for:
  6684. Assert( sc == ERROR_SUCCESS )
  6685. //
  6686. // Give ownership to the caller
  6687. //
  6688. *phClusterNameResourceOut = hClusterNameResource;
  6689. hClusterNameResource = NULL;
  6690. *phClusterIPAddressResourceOut = hClusterIPAddressResource;
  6691. hClusterIPAddressResource = NULL;
  6692. *phClusterQuorumResourceOut = hClusterQuorumResource;
  6693. hClusterQuorumResource = NULL;
  6694. Cleanup:
  6695. if ( hClusterNameResource != NULL )
  6696. {
  6697. CloseClusterResource( hClusterNameResource );
  6698. } // if:
  6699. if ( hClusterIPAddressResource != NULL )
  6700. {
  6701. CloseClusterResource( hClusterIPAddressResource );
  6702. } // if:
  6703. if ( hClusterQuorumResource != NULL )
  6704. {
  6705. CloseClusterResource( hClusterQuorumResource );
  6706. } // if:
  6707. if ( pbstr != NULL )
  6708. {
  6709. TraceSysFreeString( *pbstr );
  6710. } // if:
  6711. delete [] pszName;
  6712. HRETURN( hr );
  6713. } //*** CPostCfgManager::HrGetCoreClusterResourceNames
  6714. /*
  6715. //////////////////////////////////////////////////////////////////////////////
  6716. //
  6717. // HRESULT
  6718. // CPostCfgManager::HrIsLocalQuorum( BSTR bstrNameIn )
  6719. //
  6720. //////////////////////////////////////////////////////////////////////////////
  6721. HRESULT
  6722. CPostCfgManager::HrIsLocalQuorum( BSTR bstrNameIn )
  6723. {
  6724. TraceFunc( "" );
  6725. Assert( bstrNameIn != NULL );
  6726. HRESULT hr = S_FALSE;
  6727. BSTR bstrLocalQuorum = NULL;
  6728. hr = THR( HrLoadStringIntoBSTR( g_hInstance, IDS_LOCAL_QUORUM_DISPLAY_NAME, &bstrLocalQuorum ) );
  6729. if ( FAILED( hr ) )
  6730. {
  6731. goto Cleanup;
  6732. } // if:
  6733. if ( ClRtlStrICmp( bstrNameIn, bstrLocalQuorum ) == 0 )
  6734. {
  6735. hr = S_OK;
  6736. } // if:
  6737. else
  6738. {
  6739. hr = S_FALSE;
  6740. } // else:
  6741. Cleanup:
  6742. TraceSysFreeString( bstrLocalQuorum );
  6743. HRETURN( hr );
  6744. } //*** CPostCfgManager::HrIsLocalQuorum
  6745. */
  6746. #if defined(DEBUG)
  6747. //////////////////////////////////////////////////////////////////////////////
  6748. //
  6749. // void
  6750. // CPostCfgManager::DebugDumpDepencyTree( void )
  6751. //
  6752. //////////////////////////////////////////////////////////////////////////////
  6753. void
  6754. CPostCfgManager::DebugDumpDepencyTree( void )
  6755. {
  6756. TraceFunc( "" );
  6757. ULONG idxResource;
  6758. ULONG cDependents;
  6759. ULONG idxDependent;
  6760. BSTR bstrName; // don't free
  6761. CResourceEntry * presentry;
  6762. EDependencyFlags dfDependent;
  6763. for ( idxResource = 0; idxResource < m_cResources ; idxResource ++ )
  6764. {
  6765. presentry = m_rgpResources[ idxResource ];
  6766. THR( presentry->GetName( &bstrName ) );
  6767. DebugMsgNoNewline( "%ws(#%u) -> ", bstrName, idxResource );
  6768. THR( presentry->GetCountOfDependents( &cDependents ) );
  6769. for ( ; cDependents != 0 ; )
  6770. {
  6771. cDependents --;
  6772. THR( presentry->GetDependent( cDependents, &idxDependent, &dfDependent ) );
  6773. THR( m_rgpResources[ idxDependent ]->GetName( &bstrName ) );
  6774. DebugMsgNoNewline( "%ws(#%u) ", bstrName, idxDependent );
  6775. } // for: cDependents
  6776. DebugMsg( L"" );
  6777. } // for: idxResource
  6778. TraceFuncExit();
  6779. } //*** CPostCfgManager::DebugDumpDepencyTree
  6780. #endif // #if defined(DEBUG)