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

1577 lines
37 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CEnumClusCfgIPAddresses.cpp
  7. //
  8. // Description:
  9. // This file contains the definition of the CEnumClusCfgIPAddresses
  10. // class.
  11. //
  12. // The class CEnumClusCfgIPAddresses is the enumeration of IP addresses.
  13. // It implements the IEnumClusCfgIPAddresses interface.
  14. //
  15. // Documentation:
  16. //
  17. // Header File:
  18. // CEnumClusCfgIPAddresses.h
  19. //
  20. // Maintained By:
  21. // Galen Barbee (GalenB) 23-MAR-2000
  22. //
  23. //////////////////////////////////////////////////////////////////////////////
  24. //////////////////////////////////////////////////////////////////////////////
  25. // Include Files
  26. //////////////////////////////////////////////////////////////////////////////
  27. #include "pch.h"
  28. #include "CEnumClusCfgIPAddresses.h"
  29. #include "CClusCfgIPAddressInfo.h"
  30. #include <ClusRtl.h>
  31. #include <commctrl.h>
  32. //////////////////////////////////////////////////////////////////////////////
  33. // Constant Definitions
  34. //////////////////////////////////////////////////////////////////////////////
  35. DEFINE_THISCLASS( "CEnumClusCfgIPAddresses" );
  36. //*************************************************************************//
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CEnumClusCfgIPAddresses class
  39. /////////////////////////////////////////////////////////////////////////////
  40. //////////////////////////////////////////////////////////////////////////////
  41. //++
  42. //
  43. // CEnumClusCfgIPAddresses::S_HrCreateInstance
  44. //
  45. // Description:
  46. // Create a CEnumClusCfgIPAddresses instance.
  47. //
  48. // Arguments:
  49. // None.
  50. //
  51. // Return Values:
  52. // Pointer to CEnumClusCfgIPAddresses instance.
  53. //
  54. //--
  55. //////////////////////////////////////////////////////////////////////////////
  56. HRESULT
  57. CEnumClusCfgIPAddresses::S_HrCreateInstance( IUnknown ** ppunkOut )
  58. {
  59. TraceFunc( "" );
  60. HRESULT hr;
  61. CEnumClusCfgIPAddresses * pccsd = NULL;
  62. if ( ppunkOut == NULL )
  63. {
  64. hr = THR( E_POINTER );
  65. goto Cleanup;
  66. } // if:
  67. pccsd = new CEnumClusCfgIPAddresses();
  68. if ( pccsd == NULL )
  69. {
  70. hr = THR( E_OUTOFMEMORY );
  71. goto Cleanup;
  72. } // if: error allocating object
  73. hr = THR( pccsd->HrInit() );
  74. if ( FAILED( hr ) )
  75. {
  76. goto Cleanup;
  77. } // if: HrInit() failed
  78. hr = THR( pccsd->TypeSafeQI( IUnknown, ppunkOut ) );
  79. Cleanup:
  80. if ( FAILED( hr ) )
  81. {
  82. LogMsg( L"[SRV] CEnumClusCfgIPAddresses::S_HrCreateInstance() failed. (hr = %#08x)", hr );
  83. } // if:
  84. if ( pccsd != NULL )
  85. {
  86. pccsd->Release();
  87. } // if:
  88. HRETURN( hr );
  89. } //*** CEnumClusCfgIPAddresses::S_HrCreateInstance
  90. //////////////////////////////////////////////////////////////////////////////
  91. //++
  92. //
  93. // CEnumClusCfgIPAddresses::S_HrCreateInstance
  94. //
  95. // Description:
  96. // Create a CEnumClusCfgIPAddresses instance.
  97. //
  98. // Arguments:
  99. // None.
  100. //
  101. // Return Values:
  102. // Pointer to CEnumClusCfgIPAddresses instance.
  103. //
  104. //--
  105. //////////////////////////////////////////////////////////////////////////////
  106. HRESULT
  107. CEnumClusCfgIPAddresses::S_HrCreateInstance(
  108. ULONG ulIPAddressIn
  109. , ULONG ulIPSubnetIn
  110. , IUnknown * punkCallbackIn
  111. , LCID lcidIn
  112. , IWbemServices * pIWbemServicesIn
  113. , IUnknown ** ppunkOut
  114. )
  115. {
  116. TraceFunc( "" );
  117. Assert( ppunkOut != NULL );
  118. Assert( ulIPAddressIn != 0 );
  119. Assert( ulIPSubnetIn != 0 );
  120. HRESULT hr;
  121. CEnumClusCfgIPAddresses * pccsd = NULL;
  122. if ( ppunkOut == NULL )
  123. {
  124. hr = THR( E_POINTER );
  125. goto Cleanup;
  126. } // if:
  127. pccsd = new CEnumClusCfgIPAddresses();
  128. if ( pccsd == NULL )
  129. {
  130. hr = THR( E_OUTOFMEMORY );
  131. goto Cleanup;
  132. } // if: error allocating object
  133. hr = THR( pccsd->Initialize( punkCallbackIn, lcidIn ) );
  134. if ( FAILED( hr ) )
  135. {
  136. goto Cleanup;
  137. } // if:
  138. hr = THR( pccsd->SetWbemServices( pIWbemServicesIn ) );
  139. if ( FAILED( hr ) )
  140. {
  141. goto Cleanup;
  142. } // if:
  143. hr = THR( pccsd->HrInit( ulIPAddressIn, ulIPSubnetIn ) );
  144. if ( FAILED( hr ) )
  145. {
  146. goto Cleanup;
  147. } // if: HrInit() failed
  148. hr = THR( pccsd->TypeSafeQI( IUnknown, ppunkOut ) );
  149. Cleanup:
  150. if ( FAILED( hr ) )
  151. {
  152. LogMsg( L"[SRV] CEnumClusCfgIPAddresses::S_HrCreateInstance( ULONG, ULONG ) failed. (hr = %#08x)", hr );
  153. } // if:
  154. if ( pccsd != NULL )
  155. {
  156. pccsd->Release();
  157. } // if:
  158. HRETURN( hr );
  159. } //*** CEnumClusCfgIPAddresses::S_HrCreateInstance
  160. //////////////////////////////////////////////////////////////////////////////
  161. //++
  162. //
  163. // CEnumClusCfgIPAddresses::CEnumClusCfgIPAddresses
  164. //
  165. // Description:
  166. // Constructor of the CEnumClusCfgIPAddresses class. This initializes
  167. // the m_cRef variable to 1 instead of 0 to account of possible
  168. // QueryInterface failure in DllGetClassObject.
  169. //
  170. // Arguments:
  171. // None.
  172. //
  173. // Return Value:
  174. // None.
  175. //
  176. // Remarks:
  177. // None.
  178. //
  179. //--
  180. //////////////////////////////////////////////////////////////////////////////
  181. CEnumClusCfgIPAddresses::CEnumClusCfgIPAddresses( void )
  182. : m_cRef( 1 )
  183. , m_lcid( LOCALE_NEUTRAL )
  184. {
  185. TraceFunc( "" );
  186. Assert( m_idxNext == 0 );
  187. Assert( m_idxEnumNext == 0 );
  188. Assert( m_picccCallback == NULL );
  189. Assert( m_pIWbemServices == NULL );
  190. Assert( m_prgAddresses == NULL );
  191. Assert( m_cAddresses == 0 );
  192. // Increment the count of components in memory so the DLL hosting this
  193. // object cannot be unloaded.
  194. InterlockedIncrement( &g_cObjects );
  195. TraceFuncExit();
  196. } //*** CEnumClusCfgIPAddresses::CEnumClusCfgIPAddresses
  197. //////////////////////////////////////////////////////////////////////////////
  198. //++
  199. //
  200. // CEnumClusCfgIPAddresses::~CEnumClusCfgIPAddresses
  201. //
  202. // Description:
  203. // Desstructor of the CEnumClusCfgIPAddresses class.
  204. //
  205. // Arguments:
  206. // None.
  207. //
  208. // Return Value:
  209. // None.
  210. //
  211. // Remarks:
  212. // None.
  213. //
  214. //--
  215. //////////////////////////////////////////////////////////////////////////////
  216. CEnumClusCfgIPAddresses::~CEnumClusCfgIPAddresses( void )
  217. {
  218. TraceFunc( "" );
  219. ULONG idx;
  220. if ( m_pIWbemServices != NULL )
  221. {
  222. m_pIWbemServices->Release();
  223. } // if:
  224. if ( m_picccCallback != NULL )
  225. {
  226. m_picccCallback->Release();
  227. } // if:
  228. for ( idx = 0; idx < m_idxNext; idx++ )
  229. {
  230. ((*m_prgAddresses)[ idx ])->Release();
  231. } // for:
  232. TraceFree( m_prgAddresses );
  233. // There's going to be one less component in memory. Decrement component count.
  234. InterlockedDecrement( &g_cObjects );
  235. TraceFuncExit();
  236. } //*** CEnumClusCfgIPAddresses::~CEnumClusCfgIPAddresses
  237. //*************************************************************************//
  238. /////////////////////////////////////////////////////////////////////////////
  239. // CEnumClusCfgIPAddresses -- IUknkown interface.
  240. /////////////////////////////////////////////////////////////////////////////
  241. //////////////////////////////////////////////////////////////////////////////
  242. //++
  243. //
  244. // STDMETHODIMP_( ULONG )
  245. // CEnumClusCfgIPAddresses:: [IUNKNOWN] AddRef
  246. //
  247. // Description:
  248. // Increment the reference count of this object by one.
  249. //
  250. // Arguments:
  251. // None.
  252. //
  253. // Return Value:
  254. // The new reference count.
  255. //
  256. // Remarks:
  257. // None.
  258. //
  259. //--
  260. //////////////////////////////////////////////////////////////////////////////
  261. STDMETHODIMP_( ULONG )
  262. CEnumClusCfgIPAddresses::AddRef( void )
  263. {
  264. TraceFunc( "[IUnknown]" );
  265. InterlockedIncrement( & m_cRef );
  266. RETURN( m_cRef );
  267. } //*** CEnumClusCfgIPAddresses::AddRef
  268. //////////////////////////////////////////////////////////////////////////////
  269. //++
  270. //
  271. // STDMETHODIMP_( ULONG )
  272. // CEnumClusCfgIPAddresses:: [IUNKNOWN] Release
  273. //
  274. // Description:
  275. // Decrement the reference count of this object by one.
  276. //
  277. // Arguments:
  278. // None.
  279. //
  280. // Return Value:
  281. // The new reference count.
  282. //
  283. // Remarks:
  284. // None.
  285. //
  286. //--
  287. //////////////////////////////////////////////////////////////////////////////
  288. STDMETHODIMP_( ULONG )
  289. CEnumClusCfgIPAddresses::Release( void )
  290. {
  291. TraceFunc( "[IUnknown]" );
  292. LONG cRef;
  293. cRef = InterlockedDecrement( &m_cRef );
  294. if ( cRef == 0 )
  295. {
  296. TraceDo( delete this );
  297. } // if: reference count equal to zero
  298. RETURN( cRef );
  299. } //*** CEnumClusCfgIPAddresses::Release
  300. //////////////////////////////////////////////////////////////////////////////
  301. //++
  302. //
  303. // CEnumClusCfgIPAddresses:: [INKNOWN] QueryInterface
  304. //
  305. // Description:
  306. // Query this object for the passed in interface.
  307. //
  308. // Arguments:
  309. // IN REFIID riid,
  310. // Id of interface requested.
  311. //
  312. // OUT void ** ppv
  313. // Pointer to the requested interface.
  314. //
  315. // Return Value:
  316. // S_OK
  317. // If the interface is available on this object.
  318. //
  319. // E_NOINTERFACE
  320. // If the interface is not available.
  321. //
  322. // Remarks:
  323. // None.
  324. //
  325. //--
  326. //////////////////////////////////////////////////////////////////////////////
  327. STDMETHODIMP
  328. CEnumClusCfgIPAddresses::QueryInterface( REFIID riid, void ** ppv )
  329. {
  330. TraceQIFunc( riid, ppv );
  331. HRESULT hr = E_NOINTERFACE;
  332. if ( IsEqualIID( riid, IID_IUnknown ) )
  333. {
  334. *ppv = static_cast< IEnumClusCfgIPAddresses * >( this );
  335. hr = S_OK;
  336. } // if: IUnknown
  337. else if ( IsEqualIID( riid, IID_IEnumClusCfgIPAddresses ) )
  338. {
  339. *ppv = TraceInterface( __THISCLASS__, IEnumClusCfgIPAddresses, this, 0 );
  340. hr = S_OK;
  341. } // else if:
  342. else if ( IsEqualIID( riid, IID_IClusCfgWbemServices ) )
  343. {
  344. *ppv = TraceInterface( __THISCLASS__, IClusCfgWbemServices, this, 0 );
  345. hr = S_OK;
  346. } // else if:
  347. else if ( IsEqualIID( riid, IID_IClusCfgInitialize ) )
  348. {
  349. *ppv = TraceInterface( __THISCLASS__, IClusCfgInitialize, this, 0 );
  350. hr = S_OK;
  351. } // else if:
  352. else if ( IsEqualIID( riid, IID_IClusCfgSetWbemObject ) )
  353. {
  354. *ppv = TraceInterface( __THISCLASS__, IClusCfgSetWbemObject, this, 0 );
  355. hr = S_OK;
  356. } // else if:
  357. if ( SUCCEEDED( hr ) )
  358. {
  359. ((IUnknown *) *ppv)->AddRef( );
  360. } // if: success
  361. QIRETURN( hr, riid );
  362. } //*** CEnumClusCfgIPAddresses::QueryInterface
  363. //*************************************************************************//
  364. /////////////////////////////////////////////////////////////////////////////
  365. // CEnumClusCfgIPAddresses -- IClusCfgWbemServices interface.
  366. /////////////////////////////////////////////////////////////////////////////
  367. //////////////////////////////////////////////////////////////////////////////
  368. //++
  369. //
  370. // CEnumClusCfgIPAddresses::SetWbemServices
  371. //
  372. // Description:
  373. // Set the WBEM services provider.
  374. //
  375. // Arguments:
  376. // IN IWbemServices pIWbemServicesIn
  377. //
  378. // Return Value:
  379. // S_OK
  380. // Success
  381. //
  382. // E_POINTER
  383. // The pIWbemServicesIn param is NULL.
  384. //
  385. // Remarks:
  386. // None.
  387. //
  388. //--
  389. //////////////////////////////////////////////////////////////////////////////
  390. STDMETHODIMP
  391. CEnumClusCfgIPAddresses::SetWbemServices( IWbemServices * pIWbemServicesIn )
  392. {
  393. TraceFunc( "[IClusCfgWbemServices]" );
  394. HRESULT hr = S_OK;
  395. if ( pIWbemServicesIn == NULL )
  396. {
  397. hr = THR( E_POINTER );
  398. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_SetWbemServices_Enum_IPAddresses, IDS_ERROR_NULL_POINTER, hr );
  399. goto Cleanup;
  400. } // if:
  401. m_pIWbemServices = pIWbemServicesIn;
  402. m_pIWbemServices->AddRef();
  403. Cleanup:
  404. HRETURN( hr );
  405. } //*** CEnumClusCfgIPAddresses::SetWbemServices
  406. //*************************************************************************//
  407. /////////////////////////////////////////////////////////////////////////////
  408. // CEnumClusCfgIPAddresses -- IClusCfgInitialize interface.
  409. /////////////////////////////////////////////////////////////////////////////
  410. //////////////////////////////////////////////////////////////////////////////
  411. //++
  412. //
  413. // CEnumClusCfgIPAddresses::Initialize
  414. //
  415. // Description:
  416. // Initialize this component.
  417. //
  418. // Arguments:
  419. // IN IUknown * punkCallbackIn
  420. //
  421. // IN LCID lcidIn
  422. //
  423. // Return Value:
  424. // S_OK
  425. // Success
  426. //
  427. // Remarks:
  428. // None.
  429. //
  430. //--
  431. //////////////////////////////////////////////////////////////////////////////
  432. STDMETHODIMP
  433. CEnumClusCfgIPAddresses::Initialize(
  434. IUnknown * punkCallbackIn,
  435. LCID lcidIn
  436. )
  437. {
  438. TraceFunc( "[IClusCfgInitialize]" );
  439. Assert( m_picccCallback == NULL );
  440. HRESULT hr = S_OK;
  441. m_lcid = lcidIn;
  442. if ( punkCallbackIn == NULL )
  443. {
  444. hr = THR( E_POINTER );
  445. goto Cleanup;
  446. } // if:
  447. hr = THR( punkCallbackIn->TypeSafeQI( IClusCfgCallback, &m_picccCallback ) );
  448. Cleanup:
  449. HRETURN( hr );
  450. } //*** CEnumClusCfgIPAddresses::Initialize
  451. //*************************************************************************//
  452. /////////////////////////////////////////////////////////////////////////////
  453. // CEnumClusCfgIPAddresses -- IEnumClusCfgIPAddresses interface.
  454. /////////////////////////////////////////////////////////////////////////////
  455. //////////////////////////////////////////////////////////////////////////////
  456. //++
  457. //
  458. // CEnumClusCfgIPAddresses::Next
  459. //
  460. // Description:
  461. //
  462. // Arguments:
  463. //
  464. // Return Value:
  465. //
  466. // Remarks:
  467. // None.
  468. //
  469. //--
  470. //////////////////////////////////////////////////////////////////////////////
  471. STDMETHODIMP
  472. CEnumClusCfgIPAddresses::Next(
  473. ULONG cNumberRequestedIn,
  474. IClusCfgIPAddressInfo ** rgpIPAddressInfoOut,
  475. ULONG * pcNumberFetchedOut
  476. )
  477. {
  478. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  479. HRESULT hr = S_FALSE;
  480. ULONG cFetched = 0;
  481. ULONG idx;
  482. IClusCfgIPAddressInfo * pccipai;
  483. if ( rgpIPAddressInfoOut == NULL )
  484. {
  485. hr = THR( E_POINTER );
  486. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_Next_Enum_IPAddresses, IDS_ERROR_NULL_POINTER, hr );
  487. goto Cleanup;
  488. } // if:
  489. cFetched = min( cNumberRequestedIn, ( m_idxNext - m_idxEnumNext ) );
  490. for ( idx = 0; idx < cFetched; idx++, m_idxEnumNext++ )
  491. {
  492. hr = THR( ((*m_prgAddresses)[ m_idxEnumNext ])->TypeSafeQI( IClusCfgIPAddressInfo, &pccipai ) );
  493. if ( FAILED( hr ) )
  494. {
  495. break;
  496. } // if:
  497. rgpIPAddressInfoOut[ idx ] = pccipai;
  498. } // for:
  499. if ( FAILED( hr ) )
  500. {
  501. ULONG idxStop = idx;
  502. m_idxEnumNext -= idx;
  503. for ( idx = 0; idx < idxStop; idx++ )
  504. {
  505. (rgpIPAddressInfoOut[ idx ])->Release();
  506. } // for:
  507. cFetched = 0;
  508. goto Cleanup;
  509. } // if:
  510. if ( cFetched < cNumberRequestedIn )
  511. {
  512. hr = S_FALSE;
  513. } // if:
  514. Cleanup:
  515. if ( pcNumberFetchedOut != NULL )
  516. {
  517. *pcNumberFetchedOut = cFetched;
  518. } // if:
  519. HRETURN( hr );
  520. } //*** CEnumClusCfgIPAddresses::Next
  521. //////////////////////////////////////////////////////////////////////////////
  522. //++
  523. //
  524. // CEnumClusCfgIPAddresses::Skip
  525. //
  526. // Description:
  527. //
  528. // Arguments:
  529. //
  530. // Return Value:
  531. //
  532. // Remarks:
  533. // None.
  534. //
  535. //--
  536. //////////////////////////////////////////////////////////////////////////////
  537. STDMETHODIMP
  538. CEnumClusCfgIPAddresses::Skip( ULONG cNumberToSkipIn )
  539. {
  540. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  541. HRESULT hr = S_OK;
  542. m_idxEnumNext += cNumberToSkipIn;
  543. if ( m_idxEnumNext >= m_idxNext )
  544. {
  545. m_idxEnumNext = m_idxNext;
  546. hr = STHR( S_FALSE );
  547. } // if:
  548. HRETURN( hr );
  549. } //*** CEnumClusCfgIPAddresses::Skip
  550. //////////////////////////////////////////////////////////////////////////////
  551. //++
  552. //
  553. // CEnumClusCfgIPAddresses::Reset
  554. //
  555. // Description:
  556. //
  557. // Arguments:
  558. //
  559. // Return Value:
  560. //
  561. // Remarks:
  562. // None.
  563. //
  564. //--
  565. //////////////////////////////////////////////////////////////////////////////
  566. STDMETHODIMP
  567. CEnumClusCfgIPAddresses::Reset( void )
  568. {
  569. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  570. HRESULT hr S_OK;
  571. m_idxEnumNext = 0;
  572. HRETURN( hr );
  573. } //*** CEnumClusCfgIPAddresses::Reset
  574. //////////////////////////////////////////////////////////////////////////////
  575. //++
  576. //
  577. // CEnumClusCfgIPAddresses::Clone
  578. //
  579. // Description:
  580. //
  581. // Arguments:
  582. //
  583. // Return Value:
  584. //
  585. // Remarks:
  586. // None.
  587. //
  588. //--
  589. //////////////////////////////////////////////////////////////////////////////
  590. STDMETHODIMP
  591. CEnumClusCfgIPAddresses::Clone(
  592. IEnumClusCfgIPAddresses ** ppEnumClusCfgIPAddressesOut
  593. )
  594. {
  595. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  596. HRESULT hr = S_OK;
  597. if ( ppEnumClusCfgIPAddressesOut == NULL )
  598. {
  599. hr = THR( E_POINTER );
  600. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_Clone_Enum_IPAddresses, IDS_ERROR_NULL_POINTER, hr );
  601. goto Cleanup;
  602. } // if:
  603. hr = THR( E_NOTIMPL );
  604. Cleanup:
  605. HRETURN( hr );
  606. } //*** CEnumClusCfgIPAddresses::Clone
  607. //////////////////////////////////////////////////////////////////////////////
  608. //++
  609. //
  610. // CEnumClusCfgIPAddresses::Count
  611. //
  612. // Description:
  613. //
  614. // Arguments:
  615. //
  616. // Return Value:
  617. //
  618. // Remarks:
  619. // None.
  620. //
  621. //--
  622. //////////////////////////////////////////////////////////////////////////////
  623. STDMETHODIMP
  624. CEnumClusCfgIPAddresses::Count( DWORD * pnCountOut )
  625. {
  626. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  627. HRESULT hr = S_OK;
  628. if ( pnCountOut == NULL )
  629. {
  630. hr = THR( E_POINTER );
  631. goto Cleanup;
  632. } // if:
  633. *pnCountOut = m_cAddresses;
  634. Cleanup:
  635. HRETURN( hr );
  636. } //*** CEnumClusCfgIPAddress::Count
  637. //*************************************************************************//
  638. /////////////////////////////////////////////////////////////////////////////
  639. // CEnumClusCfgIPAddresses class -- IClusCfgNetworkAdapterInfo Interface
  640. /////////////////////////////////////////////////////////////////////////////
  641. //////////////////////////////////////////////////////////////////////////////
  642. //++
  643. //
  644. // CEnumClusCfgIPAddresses::SetWbemObject
  645. //
  646. // Description:
  647. // Get the configuration from the passed in adapter and load this
  648. // enumerator.
  649. //
  650. // Arguments:
  651. // None.
  652. //
  653. // Return Value:
  654. //
  655. //
  656. // Remarks:
  657. // None.
  658. //
  659. //--
  660. //////////////////////////////////////////////////////////////////////////////
  661. STDMETHODIMP
  662. CEnumClusCfgIPAddresses::SetWbemObject(
  663. IWbemClassObject * pNetworkAdapterIn
  664. , bool * pfRetainObjectOut
  665. )
  666. {
  667. TraceFunc( "[IClusCfgNetworkAdapterInfo]" );
  668. Assert( pfRetainObjectOut != NULL );
  669. HRESULT hr = E_INVALIDARG;
  670. if ( pNetworkAdapterIn != NULL )
  671. {
  672. hr = STHR( HrGetAdapterConfiguration( pNetworkAdapterIn ) );
  673. *pfRetainObjectOut = true;
  674. } // if:
  675. HRETURN( hr );
  676. } //*** CEnumClusCfgIPAddresses::SetWbemObject
  677. //*************************************************************************//
  678. /////////////////////////////////////////////////////////////////////////////
  679. // CEnumClusCfgIPAddresses class -- Private Methods.
  680. /////////////////////////////////////////////////////////////////////////////
  681. //////////////////////////////////////////////////////////////////////////////
  682. //++
  683. //
  684. // CEnumClusCfgIPAddresses::HrInit
  685. //
  686. // Description:
  687. // Initialize this component.
  688. //
  689. // Arguments:
  690. // None.
  691. //
  692. // Return Value:
  693. //
  694. //
  695. // Remarks:
  696. // None.
  697. //
  698. //--
  699. //////////////////////////////////////////////////////////////////////////////
  700. HRESULT
  701. CEnumClusCfgIPAddresses::HrInit( void )
  702. {
  703. TraceFunc( "" );
  704. HRESULT hr = S_OK;
  705. HRETURN( hr );
  706. } //*** CEnumClusCfgIPAddresses::HrInit
  707. //////////////////////////////////////////////////////////////////////////////
  708. //++
  709. //
  710. // CEnumClusCfgIPAddresses::HrInit
  711. //
  712. // Description:
  713. // Initialize this component.
  714. //
  715. // Arguments:
  716. // None.
  717. //
  718. // Return Value:
  719. //
  720. //
  721. // Remarks:
  722. // None.
  723. //
  724. //--
  725. //////////////////////////////////////////////////////////////////////////////
  726. HRESULT
  727. CEnumClusCfgIPAddresses::HrInit( ULONG ulIPAddressIn, ULONG ulIPSubnetIn )
  728. {
  729. TraceFunc( "" );
  730. HRESULT hr;
  731. IUnknown * punk = NULL;
  732. hr = THR( HrCreateIPAddress( ulIPAddressIn, ulIPSubnetIn, &punk ) );
  733. if ( FAILED( hr ) )
  734. {
  735. goto Cleanup;
  736. } // if:
  737. hr = THR( HrAddIPAddressToArray( punk ) );
  738. Cleanup:
  739. if ( punk != NULL )
  740. {
  741. punk->Release();
  742. } // if:
  743. HRETURN( hr );
  744. } //*** CEnumClusCfgIPAddresses::HrInit
  745. //////////////////////////////////////////////////////////////////////////////
  746. //++
  747. //
  748. // CEnumClusCfgIPAddresses::HrGetAdapterConfiguration
  749. //
  750. // Description:
  751. // Get the configuration of the passed in adapter.
  752. //
  753. // Arguments:
  754. // None.
  755. //
  756. // Return Value:
  757. //
  758. //
  759. // Remarks:
  760. // None.
  761. //
  762. //--
  763. //////////////////////////////////////////////////////////////////////////////
  764. HRESULT
  765. CEnumClusCfgIPAddresses::HrGetAdapterConfiguration(
  766. IWbemClassObject * pNetworkAdapterIn
  767. )
  768. {
  769. TraceFunc( "" );
  770. HRESULT hr = S_OK;
  771. BSTR bstrQuery = NULL;
  772. BSTR bstrWQL = NULL;
  773. VARIANT var;
  774. WCHAR sz[ 256 ];
  775. IEnumWbemClassObject * pConfigurations = NULL;
  776. ULONG ulReturned;
  777. IWbemClassObject * pConfiguration = NULL;
  778. int cFound = 0;
  779. BSTR bstrAdapterName = NULL;
  780. int idx;
  781. VariantInit( &var );
  782. bstrWQL = TraceSysAllocString( L"WQL" );
  783. if ( bstrWQL == NULL )
  784. {
  785. goto OutOfMemory;
  786. } // if:
  787. hr = THR( HrGetWMIProperty( pNetworkAdapterIn, L"DeviceID", VT_BSTR, &var ) );
  788. if ( FAILED( hr ) )
  789. {
  790. goto Cleanup;
  791. } // if:
  792. _snwprintf( sz, ARRAYSIZE( sz ), L"Associators of {Win32_NetworkAdapter.DeviceID='%s'} where AssocClass=Win32_NetworkAdapterSetting", var.bstrVal );
  793. bstrQuery = TraceSysAllocString( sz );
  794. if ( bstrQuery == NULL )
  795. {
  796. goto OutOfMemory;
  797. } // if:
  798. VariantClear( &var );
  799. hr = THR( HrGetWMIProperty( pNetworkAdapterIn, L"NetConnectionID", VT_BSTR, &var ) );
  800. if ( FAILED( hr ) )
  801. {
  802. goto Cleanup;
  803. } // if:
  804. bstrAdapterName = TraceSysAllocString( var.bstrVal );
  805. if ( bstrAdapterName == NULL )
  806. {
  807. goto OutOfMemory;
  808. } // if:
  809. hr = THR( m_pIWbemServices->ExecQuery( bstrWQL, bstrQuery, WBEM_FLAG_FORWARD_ONLY, NULL, &pConfigurations ) );
  810. if ( FAILED( hr ) )
  811. {
  812. STATUS_REPORT_STRING(
  813. TASKID_Major_Find_Devices,
  814. TASKID_Minor_WMI_NetworkAdapterSetting_Qry_Failed,
  815. IDS_ERROR_WMI_NETWORKADAPTERSETTINGS_QRY_FAILED,
  816. bstrAdapterName,
  817. hr
  818. );
  819. goto Cleanup;
  820. } // if:
  821. for ( idx = 0; ; idx++ )
  822. {
  823. hr = pConfigurations->Next( WBEM_INFINITE, 1, &pConfiguration, &ulReturned );
  824. if ( ( hr == S_OK ) && ( ulReturned == 1 ) )
  825. {
  826. //
  827. // KB: 25-AUG-2000 GalenB
  828. //
  829. // WMI only supports one configuration per adapter!
  830. //
  831. Assert( idx < 1 );
  832. VariantClear( &var );
  833. hr = THR( HrGetWMIProperty( pConfiguration, L"IPEnabled", VT_BOOL, &var ) );
  834. if ( FAILED( hr ) )
  835. {
  836. goto Cleanup;
  837. } // if:
  838. //
  839. // If this configuration is not for TCP/IP then skip it.
  840. //
  841. if ( ( var.vt != VT_BOOL ) || ( var.boolVal != VARIANT_TRUE ) )
  842. {
  843. hr = S_FALSE;
  844. STATUS_REPORT_STRING( TASKID_Major_Find_Devices, TASKID_Minor_Non_Tcp_Config, IDS_WARNING__NON_TCP_CONFIG, bstrAdapterName, hr );
  845. continue;
  846. } // if:
  847. hr = STHR( HrSaveIPAddresses( bstrAdapterName, pConfiguration ) );
  848. if ( FAILED( hr ) )
  849. {
  850. goto Cleanup;
  851. } // if:
  852. //
  853. // KB: 24-AUG-2000 GalenB
  854. //
  855. // If any configuration returns S_FALSE then we skip.
  856. //
  857. if ( hr == S_FALSE )
  858. {
  859. pConfiguration->Release();
  860. pConfiguration = NULL;
  861. continue;
  862. } // if:
  863. cFound++;
  864. pConfiguration->Release();
  865. pConfiguration = NULL;
  866. } // if:
  867. else if ( ( hr == S_FALSE ) && ( ulReturned == 0 ) )
  868. {
  869. hr = S_OK;
  870. break;
  871. } // else if:
  872. else
  873. {
  874. STATUS_REPORT_STRING( TASKID_Major_Find_Devices, TASKID_Minor_WQL_Qry_Next_Failed, IDS_ERROR_WQL_QRY_NEXT_FAILED, bstrQuery, hr );
  875. goto Cleanup;
  876. } // else:
  877. } // for:
  878. //
  879. // If we didn't find any valid configurations then we should return S_FALSE
  880. // to tell the caller to ingore that adpater.
  881. //
  882. if ( cFound == 0 )
  883. {
  884. hr = S_FALSE;
  885. STATUS_REPORT_STRING( TASKID_Major_Find_Devices, TASKID_Minor_No_Valid_TCP_Configs, IDS_WARNING_NO_VALID_TCP_CONFIGS, bstrAdapterName, hr );
  886. } // if:
  887. goto Cleanup;
  888. OutOfMemory:
  889. hr = THR( E_OUTOFMEMORY );
  890. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_HrGetAdapterConfiguration, IDS_ERROR_OUTOFMEMORY, hr );
  891. Cleanup:
  892. VariantClear( &var );
  893. TraceSysFreeString( bstrQuery );
  894. TraceSysFreeString( bstrWQL );
  895. TraceSysFreeString( bstrAdapterName );
  896. if ( pConfiguration != NULL )
  897. {
  898. pConfiguration->Release();
  899. } // if:
  900. if ( pConfigurations != NULL )
  901. {
  902. pConfigurations->Release();
  903. } // if:
  904. HRETURN( hr );
  905. } //*** CEnumClusCfgIPAddresses::HrGetAdapterConfiguration
  906. /////////////////////////////////////////////////////////////////////////////
  907. //++
  908. //
  909. // CEnumClusCfgIPAddresses:HrAddIPAddressToArray
  910. //
  911. // Description:
  912. // Add the passed in address to the array of address.
  913. //
  914. // Arguments:
  915. //
  916. //
  917. // Return Value:
  918. // S_OK
  919. // Success
  920. //
  921. // E_OUTOFMEMORY
  922. // Couldn't allocate memeory.
  923. //
  924. // Remarks:
  925. // None.
  926. //
  927. //--
  928. //////////////////////////////////////////////////////////////////////////////
  929. HRESULT
  930. CEnumClusCfgIPAddresses::HrAddIPAddressToArray( IUnknown * punkIn )
  931. {
  932. TraceFunc( "" );
  933. HRESULT hr = S_OK;
  934. IUnknown * ((*prgpunks)[]) = NULL;
  935. prgpunks = (IUnknown *((*)[])) TraceReAlloc( m_prgAddresses, sizeof( IUnknown * ) * ( m_idxNext + 1 ), HEAP_ZERO_MEMORY );
  936. if ( prgpunks == NULL )
  937. {
  938. hr = THR( E_OUTOFMEMORY );
  939. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_HrAddIPAddressToArray, IDS_ERROR_OUTOFMEMORY, hr );
  940. goto Cleanup;
  941. } // if:
  942. m_prgAddresses = prgpunks;
  943. (*m_prgAddresses)[ m_idxNext++ ] = punkIn;
  944. punkIn->AddRef();
  945. m_cAddresses += 1;
  946. Cleanup:
  947. HRETURN( hr );
  948. } //*** CEnumClusCfgIPAddresses::HrAddIPAddressToArray
  949. //////////////////////////////////////////////////////////////////////////////
  950. //++
  951. //
  952. // CEnumClusCfgIPAddresses::HrMakeDottedQuad
  953. //
  954. // Description:
  955. // Take the passed in IP address and convert it into a dotted quad.
  956. //
  957. // Arguments:
  958. // None.
  959. //
  960. // Return Value:
  961. //
  962. //
  963. // Remarks:
  964. // Internet Addresses
  965. // Values specified using the ".'' notation take one of the following forms:
  966. //
  967. // a.b.c.d a.b.c a.b a
  968. //
  969. // When four parts are specified, each is interpreted as a byte of data and
  970. // assigned, from left to right, to the 4 bytes of an Internet address. When
  971. // an Internet address is viewed as a 32-bit integer quantity on the
  972. // Intel architecture, the bytes referred to above appear as "d.c.b.a''.
  973. // That is, the bytes on an Intel processor are ordered from right to left.
  974. //
  975. // The parts that make up an address in "." notation can be decimal, octal
  976. // or hexadecimal as specified in the C language. Numbers that start
  977. // with "0x" or "0X" imply hexadecimal. Numbers that start with "0" imply
  978. // octal. All other numbers are interpreted as decimal.
  979. //
  980. //--
  981. //////////////////////////////////////////////////////////////////////////////
  982. HRESULT
  983. CEnumClusCfgIPAddresses::HrMakeDottedQuad(
  984. BSTR bstrDottedQuadIn,
  985. ULONG * pulDottedQuadOut
  986. )
  987. {
  988. TraceFunc( "" );
  989. HRESULT hr = S_OK;
  990. DWORD sc;
  991. if ( pulDottedQuadOut == NULL )
  992. {
  993. hr = THR( E_POINTER );
  994. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_HrMakeDottedQuad, IDS_ERROR_NULL_POINTER, hr );
  995. goto Cleanup;
  996. } // if:
  997. if ( bstrDottedQuadIn == NULL )
  998. {
  999. hr = THR( E_INVALIDARG );
  1000. LOG_STATUS_REPORT( L"CEnumClusCfgIPAddresses::HrMakeDottedQuad() was given an invalid argument.", hr );
  1001. goto Cleanup;
  1002. } // if:
  1003. sc = TW32( ClRtlTcpipStringToAddress( bstrDottedQuadIn, pulDottedQuadOut ) );
  1004. if ( sc != ERROR_SUCCESS )
  1005. {
  1006. hr = HRESULT_FROM_WIN32( sc );
  1007. STATUS_REPORT_STRING( TASKID_Major_Find_Devices, TASKID_Minor_Dotted_Quad_Failed, IDS_ERROR_CONVERT_TO_DOTTED_QUAD_FAILED, bstrDottedQuadIn, hr );
  1008. goto Cleanup;
  1009. } // if:
  1010. Cleanup:
  1011. RETURN( hr );
  1012. } //*** CEnumClusCfgIPAddresses::HrMakeDottedQuad
  1013. //////////////////////////////////////////////////////////////////////////////
  1014. //++
  1015. //
  1016. // CEnumClusCfgIPAddresses::HrSaveIPAddresses
  1017. //
  1018. // Description:
  1019. // Add the IP addresses to the array.
  1020. //
  1021. // Arguments:
  1022. //
  1023. //
  1024. // Return Value:
  1025. //
  1026. //
  1027. // Remarks:
  1028. // None.
  1029. //
  1030. //--
  1031. //////////////////////////////////////////////////////////////////////////////
  1032. HRESULT
  1033. CEnumClusCfgIPAddresses::HrSaveIPAddresses(
  1034. BSTR bstrAdapterNameIn,
  1035. IWbemClassObject * pConfigurationIn
  1036. )
  1037. {
  1038. TraceFunc( "" );
  1039. Assert( bstrAdapterNameIn != NULL );
  1040. Assert( pConfigurationIn != NULL );
  1041. HRESULT hr;
  1042. VARIANT varIPAddress;
  1043. VARIANT varIPSubnet;
  1044. long lIPAddressesUpperBound;
  1045. long lIPAddressesLowerBound;
  1046. long lIPSubnetsUpperBound;
  1047. long lIPSubnetsLowerBound;
  1048. long idx;
  1049. ULONG ulIPAddress;
  1050. ULONG ulIPSubnet;
  1051. BSTR bstrIPAddress = NULL;
  1052. BSTR bstrIPSubnet = NULL;
  1053. IUnknown * punk = NULL;
  1054. IClusCfgIPAddressInfo * piccipai = NULL;
  1055. VariantInit( &varIPAddress );
  1056. VariantInit( &varIPSubnet );
  1057. hr = THR( HrGetWMIProperty( pConfigurationIn, L"IPAddress", ( VT_ARRAY | VT_BSTR ), &varIPAddress ) );
  1058. if ( FAILED( hr ) )
  1059. {
  1060. goto Cleanup;
  1061. } // if:
  1062. hr = THR( HrGetWMIProperty( pConfigurationIn, L"IPSubnet", ( VT_ARRAY | VT_BSTR ), &varIPSubnet ) );
  1063. if ( FAILED( hr ) )
  1064. {
  1065. goto Cleanup;
  1066. } // if:
  1067. hr = THR( SafeArrayGetUBound( varIPAddress.parray, 1, &lIPAddressesUpperBound ) );
  1068. if ( FAILED( hr ) )
  1069. {
  1070. goto Cleanup;
  1071. } // if:
  1072. hr = THR( SafeArrayGetUBound( varIPSubnet.parray, 1, &lIPSubnetsUpperBound ) );
  1073. if ( FAILED( hr ) )
  1074. {
  1075. goto Cleanup;
  1076. } // if:
  1077. Assert( lIPAddressesUpperBound == lIPSubnetsUpperBound );
  1078. if ( lIPAddressesUpperBound != lIPSubnetsUpperBound )
  1079. {
  1080. hr = S_FALSE;
  1081. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_IP_Address_Subnet_Count_Unequal, IDS_ERROR_IP_ADDRESS_SUBNET_COUNT_UNEQUAL, hr );
  1082. goto Cleanup;
  1083. } // if:
  1084. hr = THR( SafeArrayGetLBound( varIPAddress.parray, 1, &lIPAddressesLowerBound ) );
  1085. if ( FAILED( hr ) )
  1086. {
  1087. goto Cleanup;
  1088. } // if:
  1089. hr = THR( SafeArrayGetLBound( varIPSubnet.parray, 1, &lIPSubnetsLowerBound ) );
  1090. if ( FAILED( hr ) )
  1091. {
  1092. goto Cleanup;
  1093. } // if:
  1094. Assert( lIPAddressesLowerBound == lIPSubnetsLowerBound );
  1095. if ( lIPAddressesLowerBound != lIPSubnetsLowerBound )
  1096. {
  1097. hr = S_FALSE;
  1098. STATUS_REPORT( TASKID_Major_Find_Devices, TASKID_Minor_IP_Address_Subnet_Count_Unequal, IDS_ERROR_IP_ADDRESS_SUBNET_COUNT_UNEQUAL, hr );
  1099. goto Cleanup;
  1100. } // if:
  1101. for ( idx = lIPAddressesLowerBound; idx <= lIPAddressesUpperBound; idx++ )
  1102. {
  1103. hr = THR( SafeArrayGetElement( varIPAddress.parray, &idx, &bstrIPAddress ) );
  1104. if ( FAILED( hr ) )
  1105. {
  1106. goto Cleanup;
  1107. } // if:
  1108. TraceMemoryAddBSTR( bstrIPAddress );
  1109. if ( wcscmp( bstrIPAddress, L"" ) == 0 )
  1110. {
  1111. STATUS_REPORT_STRING( TASKID_Major_Find_Devices, TASKID_Minor_Warning_No_IP_Addresses, IDS_WARNING_NO_IP_ADDRESSES, bstrAdapterNameIn, hr );
  1112. goto Cleanup;
  1113. } // end if:
  1114. hr = THR( SafeArrayGetElement( varIPSubnet.parray, &idx, &bstrIPSubnet ) );
  1115. if ( FAILED( hr ) )
  1116. {
  1117. goto Cleanup;
  1118. } // if:
  1119. Assert( bstrIPAddress != NULL );
  1120. Assert( wcslen( bstrIPAddress ) > 0 );
  1121. TraceMemoryAddBSTR( bstrIPSubnet );
  1122. LOG_STATUS_REPORT_STRING2( L"Found IP Address '%1!ws!' with subnet mask '%2!ws!'." , bstrIPAddress, bstrIPSubnet, hr );
  1123. hr = THR( HrMakeDottedQuad( bstrIPAddress, &ulIPAddress ) );
  1124. if ( FAILED( hr ) )
  1125. {
  1126. goto Cleanup;
  1127. } // if:
  1128. hr = THR( HrMakeDottedQuad( bstrIPSubnet, &ulIPSubnet ) );
  1129. if ( FAILED( hr ) )
  1130. {
  1131. goto Cleanup;
  1132. } // if:
  1133. TraceSysFreeString( bstrIPAddress );
  1134. bstrIPAddress = NULL;
  1135. TraceSysFreeString( bstrIPSubnet );
  1136. bstrIPSubnet = NULL;
  1137. hr = THR( HrCreateIPAddress( &punk ) );
  1138. if ( FAILED( hr ) )
  1139. {
  1140. goto Cleanup;
  1141. } // if:
  1142. hr = THR( punk->TypeSafeQI( IClusCfgIPAddressInfo, &piccipai ) );
  1143. if ( FAILED( hr ) )
  1144. {
  1145. goto Cleanup;
  1146. } // if:
  1147. hr = THR( piccipai->SetIPAddress( ulIPAddress ) );
  1148. if ( FAILED( hr ) )
  1149. {
  1150. goto Cleanup;
  1151. } // if:
  1152. hr = THR( piccipai->SetSubnetMask( ulIPSubnet ) );
  1153. if ( FAILED( hr ) )
  1154. {
  1155. goto Cleanup;
  1156. } // if:
  1157. piccipai->Release();
  1158. piccipai = NULL;
  1159. hr = THR( HrAddIPAddressToArray( punk ) );
  1160. if ( FAILED( hr ) )
  1161. {
  1162. goto Cleanup;
  1163. } // if:
  1164. punk->Release();
  1165. punk = NULL;
  1166. } // for:
  1167. Cleanup:
  1168. if ( piccipai != NULL )
  1169. {
  1170. piccipai->Release();
  1171. } // if:
  1172. if ( punk != NULL )
  1173. {
  1174. punk->Release();
  1175. } // if:
  1176. TraceSysFreeString( bstrIPAddress );
  1177. TraceSysFreeString( bstrIPSubnet );
  1178. VariantClear( &varIPAddress );
  1179. VariantClear( &varIPSubnet );
  1180. HRETURN( hr );
  1181. } //*** CEnumClusCfgIPAddresses::HrSaveIPAddresses
  1182. /////////////////////////////////////////////////////////////////////////////
  1183. //++
  1184. //
  1185. // CEnumClusCfgIPAddresses:HrCreateIPAddress
  1186. //
  1187. // Description:
  1188. //
  1189. //
  1190. // Arguments:
  1191. //
  1192. //
  1193. // Return Value:
  1194. // S_OK
  1195. // Success
  1196. //
  1197. // E_OUTOFMEMORY
  1198. // Couldn't allocate memeory.
  1199. //
  1200. // Remarks:
  1201. // None.
  1202. //
  1203. //--
  1204. //////////////////////////////////////////////////////////////////////////////
  1205. HRESULT
  1206. CEnumClusCfgIPAddresses::HrCreateIPAddress( IUnknown ** ppunkOut )
  1207. {
  1208. TraceFunc( "" );
  1209. Assert( ppunkOut != NULL );
  1210. HRESULT hr;
  1211. IUnknown * punk = NULL;
  1212. hr = THR( CClusCfgIPAddressInfo::S_HrCreateInstance( &punk ) );
  1213. if ( FAILED( hr ) )
  1214. {
  1215. goto Cleanup;
  1216. } // if:
  1217. punk = TraceInterface( L"CClusCfgIPAddressInfo", IUnknown, punk, 1 );
  1218. hr = THR( HrSetInitialize( punk, m_picccCallback, m_lcid ) );
  1219. if ( FAILED( hr ) )
  1220. {
  1221. goto Cleanup;
  1222. } // if:
  1223. hr = THR( HrSetWbemServices( punk, m_pIWbemServices ) );
  1224. if ( FAILED( hr ) )
  1225. {
  1226. goto Cleanup;
  1227. } // if:
  1228. *ppunkOut = punk;
  1229. (*ppunkOut)->AddRef();
  1230. Cleanup:
  1231. if ( punk != NULL )
  1232. {
  1233. punk->Release();
  1234. } // if:
  1235. HRETURN( hr );
  1236. } //*** CEnumClusCfgIPAddresses::HrCreateIPAddress
  1237. /////////////////////////////////////////////////////////////////////////////
  1238. //++
  1239. //
  1240. // CEnumClusCfgIPAddresses:HrCreateIPAddress
  1241. //
  1242. // Description:
  1243. //
  1244. //
  1245. // Arguments:
  1246. //
  1247. //
  1248. // Return Value:
  1249. // S_OK
  1250. // Success
  1251. //
  1252. // E_OUTOFMEMORY
  1253. // Couldn't allocate memeory.
  1254. //
  1255. // Remarks:
  1256. // None.
  1257. //
  1258. //--
  1259. //////////////////////////////////////////////////////////////////////////////
  1260. HRESULT
  1261. CEnumClusCfgIPAddresses::HrCreateIPAddress(
  1262. ULONG ulIPAddressIn
  1263. , ULONG ulIPSubnetIn
  1264. , IUnknown ** ppunkOut
  1265. )
  1266. {
  1267. TraceFunc( "" );
  1268. Assert( ppunkOut != NULL );
  1269. HRESULT hr;
  1270. IUnknown * punk = NULL;
  1271. hr = THR( CClusCfgIPAddressInfo::S_HrCreateInstance( ulIPAddressIn, ulIPSubnetIn, &punk ) );
  1272. if ( FAILED( hr ) )
  1273. {
  1274. goto Cleanup;
  1275. } // if:
  1276. punk = TraceInterface( L"CClusCfgIPAddressInfo", IUnknown, punk, 1 );
  1277. hr = THR( HrSetInitialize( punk, m_picccCallback, m_lcid ) );
  1278. if ( FAILED( hr ) )
  1279. {
  1280. goto Cleanup;
  1281. } // if:
  1282. hr = THR( HrSetWbemServices( punk, m_pIWbemServices ) );
  1283. if ( FAILED( hr ) )
  1284. {
  1285. goto Cleanup;
  1286. } // if:
  1287. *ppunkOut = punk;
  1288. (*ppunkOut)->AddRef();
  1289. Cleanup:
  1290. if ( punk != NULL )
  1291. {
  1292. punk->Release();
  1293. } // if:
  1294. HRETURN( hr );
  1295. } //*** CEnumClusCfgIPAddresses::HrCreateIPAddress