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.

788 lines
21 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // Cluster.cpp
  7. //
  8. // Description:
  9. // Implementation of CCluster class
  10. //
  11. // Author:
  12. // Henry Wang (HenryWa) 24-AUG-1999
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. #include "Pch.h"
  16. #include "Cluster.h"
  17. #include "clusrtl.h"
  18. //****************************************************************************
  19. //
  20. // CCluster
  21. //
  22. //****************************************************************************
  23. //////////////////////////////////////////////////////////////////////////////
  24. //++
  25. //
  26. // CCluster::CCluster
  27. //
  28. // Description:
  29. // Constructor.
  30. //
  31. // Arguments:
  32. // pwszNameIn -- Class name
  33. // pNamespaceIn -- Namespace
  34. //
  35. // Return Values:
  36. // None.
  37. //
  38. //--
  39. //////////////////////////////////////////////////////////////////////////////
  40. CCluster::CCluster(
  41. LPCWSTR pwszNameIn,
  42. CWbemServices * pNamespaceIn
  43. )
  44. : CProvBase( pwszNameIn, pNamespaceIn )
  45. {
  46. } //*** CCluster::CCluster()
  47. //////////////////////////////////////////////////////////////////////////////
  48. //++
  49. //
  50. // static
  51. // CCluster::S_CreateThis
  52. //
  53. // Description:
  54. // Create a cluster object
  55. //
  56. // Arguments:
  57. // pwszNameIn -- Class name
  58. // pNamespaceIn -- Namespace
  59. // dwEnumTypeIn -- Type id
  60. //
  61. // Return Values:
  62. // pointer to the CProvBase
  63. //
  64. //--
  65. //////////////////////////////////////////////////////////////////////////////
  66. CProvBase *
  67. CCluster::S_CreateThis(
  68. LPCWSTR pwszNameIn,
  69. CWbemServices * pNamespaceIn,
  70. DWORD // dwEnumTypeIn
  71. )
  72. {
  73. return new CCluster( pwszNameIn, pNamespaceIn );
  74. } //*** CCluster::S_CreateThis()
  75. //////////////////////////////////////////////////////////////////////////////
  76. //++
  77. //
  78. // CCluster::GetPropMap
  79. //
  80. // Description:
  81. // Retrieve the property maping table of the cluster.
  82. //
  83. // Arguments:
  84. // None.
  85. //
  86. // Return Values:
  87. // reference to the array of property maping table
  88. //
  89. //--
  90. //////////////////////////////////////////////////////////////////////////////
  91. const SPropMapEntryArray *
  92. CCluster::RgGetPropMap( void )
  93. {
  94. static SPropMapEntry s_rgpm[] =
  95. {
  96. {
  97. PVD_PROP_CLUSTER_SECURITYDESCRIPTOR,
  98. CLUSREG_NAME_CLUS_SD,
  99. MULTI_SZ_TYPE,
  100. READWRITE
  101. },
  102. {
  103. PVD_PROP_CLUSTER_GROUPADMIN,
  104. CLUS_CLUS_GROUPADMIN,
  105. MULTI_SZ_TYPE,
  106. READWRITE
  107. },
  108. {
  109. PVD_PROP_CLUSTER_NETWORKADMIN,
  110. CLUS_CLUS_NETWORKADMIN,
  111. MULTI_SZ_TYPE,
  112. READWRITE
  113. },
  114. {
  115. PVD_PROP_CLUSTER_NETINTFACEADMIN,
  116. CLUS_CLUS_NETINTERFACEADMIN,
  117. MULTI_SZ_TYPE,
  118. READWRITE
  119. },
  120. {
  121. PVD_PROP_CLUSTER_NODEADMIN,
  122. CLUS_CLUS_NODEADMIN,
  123. MULTI_SZ_TYPE,
  124. READWRITE
  125. },
  126. {
  127. PVD_PROP_CLUSTER_RESADMIN,
  128. CLUS_CLUS_RESADMIN,
  129. MULTI_SZ_TYPE,
  130. READWRITE
  131. },
  132. {
  133. PVD_PROP_CLUSTER_RESTYPEADMIN,
  134. CLUS_CLUS_RESTYPEADMIN,
  135. MULTI_SZ_TYPE,
  136. READWRITE
  137. }
  138. };
  139. static SPropMapEntryArray s_pmea (
  140. sizeof( s_rgpm ) / sizeof( SPropMapEntry ),
  141. s_rgpm
  142. );
  143. return &s_pmea;
  144. } //*** CCluster::GetPropMap()
  145. //////////////////////////////////////////////////////////////////////////////
  146. //++
  147. //
  148. // CCluster::EnumInstance
  149. //
  150. // Description:
  151. // Enum cluster instance.
  152. //
  153. // Arguments:
  154. // lFlagsIn -- WMI flag
  155. // pCtxIn -- WMI context
  156. // pHandlerIn -- WMI sink pointer
  157. //
  158. // Return Values:
  159. // WBEM_S_NO_ERROR
  160. //
  161. //--
  162. //////////////////////////////////////////////////////////////////////////////
  163. SCODE
  164. CCluster::EnumInstance(
  165. long lFlagsIn,
  166. IWbemContext * pCtxIn,
  167. IWbemObjectSink * pHandlerIn
  168. )
  169. {
  170. SAFECLUSTER shCluster;
  171. shCluster = OpenCluster( NULL );
  172. ClusterToWMI( shCluster, pHandlerIn );
  173. return WBEM_S_NO_ERROR;
  174. } //*** CCluster::EnumInstance()
  175. //////////////////////////////////////////////////////////////////////////////
  176. //++
  177. //
  178. // CCluster::ClusterToWMI
  179. //
  180. // Description:
  181. // Translate a cluster objects to WMI object.
  182. //
  183. // Arguments:
  184. // hClusterIn -- Handle to cluster
  185. // pHandlerIn -- Pointer to WMI sink
  186. //
  187. // Return Values:
  188. // WBEM_S_NO_ERROR
  189. // win32 error
  190. //
  191. //--
  192. //////////////////////////////////////////////////////////////////////////////
  193. void
  194. CCluster::ClusterToWMI(
  195. HCLUSTER hClusterIn,
  196. IWbemObjectSink * pHandlerIn
  197. )
  198. {
  199. static SGetControl s_rgControl[] =
  200. {
  201. { CLUSCTL_CLUSTER_GET_RO_COMMON_PROPERTIES, FALSE },
  202. { CLUSCTL_CLUSTER_GET_COMMON_PROPERTIES, FALSE },
  203. { CLUSCTL_CLUSTER_GET_RO_PRIVATE_PROPERTIES, TRUE },
  204. { CLUSCTL_CLUSTER_GET_PRIVATE_PROPERTIES, TRUE }
  205. };
  206. static UINT s_cControl = sizeof( s_rgControl ) / sizeof( SGetControl );
  207. DWORD dwError = ERROR_SUCCESS;
  208. CError er;
  209. UINT idx;
  210. CWbemClassObject wco;
  211. m_pClass->SpawnInstance( 0, &wco );
  212. for ( idx = 0 ; idx < s_cControl ; idx++ )
  213. {
  214. CClusPropList pl;
  215. er = pl.ScGetClusterProperties(
  216. hClusterIn,
  217. s_rgControl[ idx ].dwControl,
  218. NULL,
  219. 0
  220. );
  221. CClusterApi::GetObjectProperties(
  222. RgGetPropMap(),
  223. pl,
  224. wco,
  225. s_rgControl[ idx ].fPrivate
  226. );
  227. } // for: each common property type
  228. //
  229. // cluster name
  230. //
  231. {
  232. DWORD cchClusterName = MAX_PATH;
  233. CWstrBuf wsbClusterName;
  234. wsbClusterName.SetSize( cchClusterName );
  235. dwError = GetClusterInformation(
  236. hClusterIn,
  237. wsbClusterName,
  238. &cchClusterName,
  239. NULL
  240. );
  241. if ( dwError == ERROR_MORE_DATA )
  242. {
  243. wsbClusterName.SetSize( ++cchClusterName );
  244. er = GetClusterInformation(
  245. hClusterIn,
  246. wsbClusterName,
  247. &cchClusterName,
  248. NULL
  249. );
  250. } // if: buffer was too small
  251. wco.SetProperty( wsbClusterName, PVD_PROP_CLUSTER_NAME );
  252. }
  253. //
  254. // network priority
  255. //
  256. {
  257. LPCWSTR pwszNetworks;
  258. BSTR pbstrNetworks[ MAX_PATH ];
  259. UINT cSize;
  260. idx = 0;
  261. CClusterEnum cluEnum( hClusterIn, (DWORD) CLUSTER_ENUM_INTERNAL_NETWORK );
  262. // bugbug can you always clean up
  263. while ( ( pwszNetworks = cluEnum.GetNext() ) != NULL )
  264. {
  265. pbstrNetworks[ idx ] = SysAllocString( pwszNetworks );
  266. idx++;
  267. }
  268. wco.SetProperty(
  269. idx,
  270. pbstrNetworks,
  271. PVD_PROP_CLUSTER_NETWORK
  272. );
  273. cSize = idx;
  274. for ( idx = 0 ; idx < cSize ; idx++ )
  275. {
  276. SysFreeString( pbstrNetworks[ idx ] );
  277. }
  278. }
  279. //
  280. // quorum resource
  281. //
  282. {
  283. CWstrBuf wsbName;
  284. DWORD cchName = MAX_PATH ;
  285. CWstrBuf wsbDeviceName;
  286. DWORD cchDeviceName = MAX_PATH;
  287. DWORD dwLogSize;
  288. wsbName.SetSize( cchName );
  289. wsbDeviceName.SetSize( cchDeviceName );
  290. dwError = GetClusterQuorumResource(
  291. hClusterIn,
  292. wsbName,
  293. &cchName,
  294. wsbDeviceName,
  295. &cchDeviceName,
  296. &dwLogSize
  297. );
  298. if ( dwError == ERROR_MORE_DATA )
  299. {
  300. wsbName.SetSize( ++cchName );
  301. wsbDeviceName.SetSize( ++cchDeviceName );
  302. er = GetClusterQuorumResource(
  303. hClusterIn,
  304. wsbName,
  305. &cchName,
  306. wsbDeviceName,
  307. &cchDeviceName,
  308. &dwLogSize
  309. );
  310. }
  311. wco.SetProperty( wsbDeviceName, PVD_PROP_CLUSTER_FILE );
  312. wco.SetProperty( dwLogSize, PVD_PROP_CLUSTER_LOGSIZE );
  313. }
  314. //
  315. // max nodes in cluster
  316. //
  317. {
  318. DWORD maxNodesInCluster;
  319. maxNodesInCluster = ClRtlGetDefaultNodeLimit( ClRtlGetSuiteType() );
  320. wco.SetProperty( maxNodesInCluster, PVD_PROP_CLUSTER_MAX_NODES );
  321. }
  322. pHandlerIn->Indicate( 1, &wco );
  323. return;
  324. } //*** CCluster::ClusterToWMI()
  325. //////////////////////////////////////////////////////////////////////////////
  326. //++
  327. //
  328. // CCluster::GetObject
  329. //
  330. // Description:
  331. // retrieve cluster object based given object path
  332. //
  333. // Arguments:
  334. // rObjPathIn -- Object path to cluster object
  335. // lFlagsIn -- WMI flag
  336. // pCtxIn -- WMI context
  337. // pHandlerIn -- WMI sink pointer
  338. //
  339. // Return Values:
  340. // WBEM_S_NO_ERROR
  341. // win32 error
  342. //
  343. //--
  344. //////////////////////////////////////////////////////////////////////////////
  345. SCODE
  346. CCluster::GetObject(
  347. CObjPath & rObjPathIn,
  348. long lFlagsIn,
  349. IWbemContext * pCtxIn,
  350. IWbemObjectSink * pHandlerIn
  351. )
  352. {
  353. SAFECLUSTER shCluster;
  354. shCluster = OpenCluster( NULL );
  355. ClusterToWMI( shCluster, pHandlerIn );
  356. return WBEM_S_NO_ERROR;
  357. } //*** CCluster::GetObject()
  358. //////////////////////////////////////////////////////////////////////////////
  359. //++
  360. //
  361. // CCluster::ExecuteMethod
  362. //
  363. // Description:
  364. // execute methods defined in the mof for cluster
  365. //
  366. // Arguments:
  367. // rObjPathIn -- Object path to cluster object
  368. // pwszMethodNameIn -- Name of the method to be invoked
  369. // lFlagIn -- WMI flag
  370. // pParamsIn -- Input parameters for the method
  371. // pHandlerIn -- WMI sink pointer
  372. //
  373. // Return Values:
  374. // WBEM_S_NO_ERROR
  375. //
  376. //--
  377. //////////////////////////////////////////////////////////////////////////////
  378. SCODE
  379. CCluster::ExecuteMethod(
  380. CObjPath & rObjPathIn,
  381. WCHAR * pwszMethodNameIn,
  382. long lFlagIn,
  383. IWbemClassObject * pParamsIn,
  384. IWbemObjectSink * pHandlerIn
  385. )
  386. {
  387. SAFECLUSTER shCluster;
  388. CWbemClassObject InArgs( pParamsIn );
  389. IWbemClassObject * pIOutClass = NULL;
  390. IWbemClassObject * pIOutParams = NULL;
  391. HRESULT hr = WBEM_S_NO_ERROR;
  392. CError er;
  393. if ( ClRtlStrICmp( pwszMethodNameIn, PVD_MTH_CLUSTER_GETNODECLUSTERSTATE ) == 0 )
  394. {
  395. DWORD dwState = 0;
  396. VARIANT varClusterState;
  397. //
  398. // GetNodeClusterState Method: Get the current state of the node we are bound.
  399. //
  400. er = GetNodeClusterState( NULL, &dwState );
  401. //
  402. // Now we have the node state, we need to pass this information as an output parameter.
  403. //
  404. er = m_pClass->GetMethod( _bstr_t( PVD_MTH_CLUSTER_GETNODECLUSTERSTATE ), 0, NULL, &pIOutClass );
  405. //
  406. // We can not use er (we'll use hr) from this point on. We can't throw an exception since we need to release
  407. // pIOutClass and pIOutParams before throwing an exception in case of a failure.
  408. //
  409. hr = pIOutClass->SpawnInstance( 0, &pIOutParams );
  410. if ( FAILED( hr ) )
  411. {
  412. goto Cleanup;
  413. }
  414. VariantClear( &varClusterState );
  415. varClusterState.vt = VT_I4;
  416. varClusterState.lVal = dwState;
  417. hr = pIOutParams->Put(
  418. _bstr_t( PVD_MTH_CLUSTER_PARM_CLUSTERSTATE ),
  419. 0,
  420. &varClusterState,
  421. 0
  422. );
  423. if ( FAILED( hr ) )
  424. {
  425. goto Cleanup;
  426. }
  427. hr = pHandlerIn->Indicate( 1, &pIOutParams );
  428. if ( FAILED( hr ) )
  429. {
  430. goto Cleanup;
  431. }
  432. } // if: get node cluster state
  433. else if ( ClRtlStrICmp( pwszMethodNameIn, PVD_MTH_CLUSTER_RENAME ) == 0 )
  434. {
  435. _bstr_t bstrName;
  436. DWORD dwReturn;
  437. //
  438. // Do not move OpenCluster above the GetNodeClusterState method.
  439. // GetNodeClusterState method is supposed to work when there's no cluster.
  440. //
  441. shCluster = OpenCluster( NULL );
  442. InArgs.GetProperty( bstrName, PVD_MTH_CLUSTER_PARM_NEWNAME );
  443. dwReturn = SetClusterName( shCluster, bstrName );
  444. if ( dwReturn != ERROR_RESOURCE_PROPERTIES_STORED )
  445. {
  446. er = dwReturn;
  447. }
  448. } // if: create new group
  449. else if( ClRtlStrICmp( pwszMethodNameIn, PVD_MTH_CLUSTER_SETQUORUM ) == 0 )
  450. {
  451. _bstr_t bstrName;
  452. SAFERESOURCE hResource;
  453. //
  454. // Do not move OpenCluster above the GetNodeClusterState method.
  455. // GetNodeClusterState method is supposed to work when there's no cluster.
  456. //
  457. shCluster = OpenCluster( NULL );
  458. InArgs.GetProperty( bstrName, PVD_MTH_CLUSTER_PARM_RESOURCE );
  459. hResource = OpenClusterResource( shCluster, bstrName );
  460. er = SetClusterQuorumResource(
  461. hResource,
  462. NULL,
  463. 64000
  464. );
  465. } // else if: set quorum resource
  466. Cleanup:
  467. //
  468. // Release the interfaces
  469. //
  470. if ( pIOutClass != NULL )
  471. {
  472. pIOutClass->Release();
  473. }
  474. if ( pIOutParams != NULL )
  475. {
  476. pIOutParams->Release();
  477. }
  478. //
  479. // Now throw an exception if hr is FAILED
  480. //
  481. if ( FAILED( hr ) )
  482. {
  483. er = hr;
  484. }
  485. return hr;
  486. } //*** CCluster::ExecuteMethod()
  487. //////////////////////////////////////////////////////////////////////////////
  488. //++
  489. //
  490. // CCluster::PutInstance
  491. //
  492. // Description:
  493. // save this instance
  494. //
  495. // Arguments:
  496. // rInstToPutIn -- WMI object to be saved
  497. // lFlagIn -- WMI flag
  498. // pCtxIn -- WMI context
  499. // pHandlerIn -- WMI sink pointer
  500. //
  501. // Return Values:
  502. // WBEM_S_NO_ERROR
  503. //
  504. //--
  505. //////////////////////////////////////////////////////////////////////////////
  506. SCODE
  507. CCluster::PutInstance(
  508. CWbemClassObject & rInstToPutIn,
  509. long lFlagIn,
  510. IWbemContext * pCtxIn,
  511. IWbemObjectSink * pHandlerIn
  512. )
  513. {
  514. static SGetSetControl s_rgControl[] =
  515. {
  516. {
  517. CLUSCTL_CLUSTER_GET_COMMON_PROPERTIES,
  518. CLUSCTL_CLUSTER_SET_COMMON_PROPERTIES,
  519. FALSE
  520. },
  521. {
  522. CLUSCTL_CLUSTER_GET_PRIVATE_PROPERTIES,
  523. CLUSCTL_CLUSTER_SET_PRIVATE_PROPERTIES,
  524. TRUE
  525. }
  526. };
  527. static DWORD s_cControl = sizeof( s_rgControl ) / sizeof( SGetSetControl );
  528. CError er;
  529. DWORD dwError;
  530. SAFECLUSTER shCluster;
  531. UINT idx;
  532. shCluster = OpenCluster( NULL );
  533. for ( idx = 0 ; idx < s_cControl ; idx++ )
  534. {
  535. CClusPropList plOld;
  536. CClusPropList plNew;
  537. er = plOld.ScGetClusterProperties(
  538. shCluster,
  539. s_rgControl[ idx ].dwGetControl,
  540. NULL,
  541. NULL,
  542. 0
  543. );
  544. CClusterApi::SetObjectProperties(
  545. RgGetPropMap(),
  546. plNew,
  547. plOld,
  548. rInstToPutIn,
  549. s_rgControl[ idx ].fPrivate
  550. );
  551. if ( plNew.Cprops() > 0 )
  552. {
  553. er = ClusterControl(
  554. shCluster,
  555. NULL,
  556. s_rgControl[ idx ].dwSetControl,
  557. plNew.PbPropList(),
  558. static_cast< DWORD >( plNew.CbPropList() ),
  559. NULL,
  560. 0,
  561. NULL
  562. );
  563. }
  564. } // for: each control code
  565. //
  566. // network
  567. //
  568. {
  569. CClusPropList plNetwork;
  570. DWORD cNetworks = 0;
  571. _bstr_t * pbstrNetworks = NULL;
  572. HNETWORK * phNetworks = NULL;
  573. idx = 0;
  574. rInstToPutIn.GetProperty(
  575. &cNetworks,
  576. &pbstrNetworks,
  577. PVD_PROP_CLUSTER_NETWORK
  578. );
  579. try
  580. {
  581. phNetworks = new HNETWORK[ cNetworks ];
  582. for( idx = 0 ; idx < cNetworks ; idx++ )
  583. {
  584. *(phNetworks + idx) = NULL;
  585. }
  586. for ( idx = 0 ; idx < cNetworks ; idx++)
  587. {
  588. *( phNetworks + idx ) = OpenClusterNetwork(
  589. shCluster,
  590. *( pbstrNetworks + idx ) );
  591. if ( phNetworks == NULL )
  592. {
  593. throw CProvException( GetLastError() );
  594. }
  595. }
  596. er = SetClusterNetworkPriorityOrder(
  597. shCluster,
  598. cNetworks,
  599. phNetworks
  600. );
  601. } // try
  602. catch ( ... )
  603. {
  604. for ( idx = 0 ; idx < cNetworks ; idx++)
  605. {
  606. if ( *( phNetworks + idx ) )
  607. {
  608. CloseClusterNetwork( *( phNetworks + idx) );
  609. }
  610. }
  611. delete [] phNetworks;
  612. delete [] pbstrNetworks;
  613. throw;
  614. } // catch: ...
  615. //
  616. // clean up
  617. //
  618. for ( idx = 0 ; idx < cNetworks ; idx++)
  619. {
  620. if ( *( phNetworks + idx ) )
  621. {
  622. CloseClusterNetwork( *( phNetworks + idx) );
  623. }
  624. }
  625. delete [] phNetworks;
  626. delete [] pbstrNetworks;
  627. }
  628. //
  629. // quorum resource
  630. //
  631. {
  632. CWstrBuf wsbName;
  633. DWORD cchName = MAX_PATH;
  634. CWstrBuf wsbDeviceName;
  635. DWORD cchDeviceName = MAX_PATH;
  636. DWORD dwLogSize;
  637. _bstr_t bstrNewDeviceName;
  638. DWORD dwNewLogSize;
  639. SAFERESOURCE shResource;
  640. wsbName.SetSize( cchName );
  641. wsbDeviceName.SetSize( cchDeviceName );
  642. dwError = GetClusterQuorumResource(
  643. shCluster,
  644. wsbName,
  645. &cchName,
  646. wsbDeviceName,
  647. &cchDeviceName,
  648. &dwLogSize
  649. );
  650. if ( dwError == ERROR_MORE_DATA )
  651. {
  652. wsbName.SetSize( ++cchName );
  653. wsbDeviceName.SetSize( ++cchDeviceName );
  654. er = GetClusterQuorumResource(
  655. shCluster,
  656. wsbName,
  657. &cchName,
  658. wsbDeviceName,
  659. &cchDeviceName,
  660. &dwLogSize
  661. );
  662. } // if: buffer is too small
  663. rInstToPutIn.GetProperty( bstrNewDeviceName, PVD_PROP_CLUSTER_FILE );
  664. rInstToPutIn.GetProperty( &dwNewLogSize, PVD_PROP_CLUSTER_LOGSIZE );
  665. if ( ClRtlStrICmp( wsbDeviceName, bstrNewDeviceName )
  666. || dwLogSize != dwNewLogSize )
  667. {
  668. shResource = OpenClusterResource( shCluster, wsbName );
  669. er = SetClusterQuorumResource(
  670. shResource,
  671. bstrNewDeviceName,
  672. dwNewLogSize
  673. );
  674. } // if:
  675. }
  676. return WBEM_S_NO_ERROR;
  677. } //*** CCluster::PutInstance()
  678. //////////////////////////////////////////////////////////////////////////////
  679. //++
  680. //
  681. // CCluster::DeleteInstance
  682. //
  683. // Description:
  684. // save this instance
  685. //
  686. // Arguments:
  687. // rObjPathIn -- ObjPath for the instance to be deleted
  688. // lFlagIn -- WMI flag
  689. // pCtxIn -- WMI context
  690. // pHandlerIn -- WMI sink pointer
  691. //
  692. // Return Values:
  693. // WBEM_S_NO_ERROR
  694. //
  695. //--
  696. //////////////////////////////////////////////////////////////////////////////
  697. SCODE
  698. CCluster::DeleteInstance(
  699. CObjPath & rObjPathIn,
  700. long lFlagIn,
  701. IWbemContext * pCtxIn,
  702. IWbemObjectSink * pHandlerIn
  703. )
  704. {
  705. return WBEM_E_NOT_SUPPORTED;
  706. } //*** CCluster::DeleteInstance()