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.

729 lines
16 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // EnumIPAddresses.cpp
  7. //
  8. // Description:
  9. // CEnumIPAddress implementation.
  10. //
  11. // Maintained By:
  12. // Galen Barbee (GalenB) 24-MAY-2000
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. #include "Pch.h"
  16. #include "IPAddressInfo.h"
  17. #include "EnumIPAddresses.h"
  18. DEFINE_THISCLASS("CEnumIPAddresses")
  19. // ************************************************************************
  20. //
  21. // Constructor / Destructor
  22. //
  23. // ************************************************************************
  24. //////////////////////////////////////////////////////////////////////////////
  25. //
  26. // HRESULT
  27. // CEnumIPAddresses::S_HrCreateInstance(
  28. // IUnknown ** ppunkOut
  29. // )
  30. //
  31. //////////////////////////////////////////////////////////////////////////////
  32. HRESULT
  33. CEnumIPAddresses::S_HrCreateInstance(
  34. IUnknown ** ppunkOut
  35. )
  36. {
  37. TraceFunc( "" );
  38. HRESULT hr = S_OK;
  39. CEnumIPAddresses * peipa = NULL;
  40. Assert( ppunkOut != NULL );
  41. if ( ppunkOut == NULL )
  42. {
  43. hr = THR( E_POINTER );
  44. goto Cleanup;
  45. }
  46. peipa = new CEnumIPAddresses;
  47. if ( peipa == NULL )
  48. {
  49. hr = THR( E_OUTOFMEMORY );
  50. goto Cleanup;
  51. }
  52. hr = THR( peipa->HrInit() );
  53. if ( FAILED( hr ) )
  54. {
  55. goto Cleanup;
  56. }
  57. hr = THR( peipa->TypeSafeQI( IUnknown, ppunkOut ) );
  58. if ( FAILED( hr ) )
  59. {
  60. goto Cleanup;
  61. }
  62. Cleanup:
  63. if ( peipa != NULL )
  64. {
  65. peipa->Release();
  66. }
  67. HRETURN( hr );
  68. } //*** CEnumIPAddresses::S_HrCreateInstance
  69. //////////////////////////////////////////////////////////////////////////////
  70. //
  71. // CEnumIPAddresses::CEnumIPAddresses
  72. //
  73. //////////////////////////////////////////////////////////////////////////////
  74. CEnumIPAddresses::CEnumIPAddresses( void )
  75. : m_cRef( 1 )
  76. {
  77. TraceFunc( "" );
  78. InterlockedIncrement( &g_cObjects );
  79. TraceFuncExit();
  80. } //*** CEnumIPAddresses::CEnumIPAddresses
  81. //////////////////////////////////////////////////////////////////////////////
  82. //
  83. // STDMETHODIMP
  84. // CEnumIPAddresses::HrInit
  85. //
  86. //////////////////////////////////////////////////////////////////////////////
  87. STDMETHODIMP
  88. CEnumIPAddresses::HrInit( void )
  89. {
  90. TraceFunc( "" );
  91. HRESULT hr = S_OK;
  92. // IUnknown stuff
  93. Assert( m_cRef == 1 );
  94. // IEnumClusCfgIPAddresses
  95. HRETURN( hr );
  96. } //*** CEnumIPAddresses::HrInit
  97. //////////////////////////////////////////////////////////////////////////////
  98. //
  99. // CEnumIPAddresses::~CEnumIPAddresses
  100. //
  101. //////////////////////////////////////////////////////////////////////////////
  102. CEnumIPAddresses::~CEnumIPAddresses( void )
  103. {
  104. TraceFunc( "" );
  105. if ( m_pList != NULL )
  106. {
  107. while ( m_cAlloced != 0 )
  108. {
  109. m_cAlloced --;
  110. (m_pList[ m_cAlloced ])->Release();
  111. }
  112. }
  113. InterlockedDecrement( &g_cObjects );
  114. TraceFuncExit();
  115. } //*** CEnumIPAddresses::~CEnumIPAddresses
  116. // ************************************************************************
  117. //
  118. // IUnknown
  119. //
  120. // ************************************************************************
  121. //////////////////////////////////////////////////////////////////////////////
  122. //++
  123. //
  124. // CEnumIPAddresses::QueryInterface
  125. //
  126. // Description:
  127. // Query this object for the passed in interface.
  128. //
  129. // Arguments:
  130. // riidIn
  131. // Id of interface requested.
  132. //
  133. // ppvOut
  134. // Pointer to the requested interface.
  135. //
  136. // Return Value:
  137. // S_OK
  138. // If the interface is available on this object.
  139. //
  140. // E_NOINTERFACE
  141. // If the interface is not available.
  142. //
  143. // E_POINTER
  144. // ppvOut was NULL.
  145. //
  146. // Remarks:
  147. // None.
  148. //
  149. //--
  150. //////////////////////////////////////////////////////////////////////////////
  151. STDMETHODIMP
  152. CEnumIPAddresses::QueryInterface(
  153. REFIID riidIn
  154. , LPVOID * ppvOut
  155. )
  156. {
  157. TraceQIFunc( riidIn, ppvOut );
  158. HRESULT hr = S_OK;
  159. //
  160. // Validate arguments.
  161. //
  162. Assert( ppvOut != NULL );
  163. if ( ppvOut == NULL )
  164. {
  165. hr = THR( E_POINTER );
  166. goto Cleanup;
  167. }
  168. //
  169. // Handle known interfaces.
  170. //
  171. if ( IsEqualIID( riidIn, IID_IUnknown ) )
  172. {
  173. *ppvOut = static_cast< IEnumClusCfgIPAddresses * >( this );
  174. } // if: IUnknown
  175. else if ( IsEqualIID( riidIn, IID_IEnumClusCfgIPAddresses ) )
  176. {
  177. *ppvOut = TraceInterface( __THISCLASS__, IEnumClusCfgIPAddresses, this, 0 );
  178. } // else if: IEnumClusCfgIPAddresses
  179. else if ( IsEqualIID( riidIn, IID_IExtendObjectManager ) )
  180. {
  181. *ppvOut = TraceInterface( __THISCLASS__, IExtendObjectManager, this, 0 );
  182. } // else if: IExtendObjectManager
  183. else
  184. {
  185. *ppvOut = NULL;
  186. hr = E_NOINTERFACE;
  187. } // else
  188. //
  189. // Add a reference to the interface if successful.
  190. //
  191. if ( SUCCEEDED( hr ) )
  192. {
  193. ((IUnknown *) *ppvOut)->AddRef();
  194. } // if: success
  195. Cleanup:
  196. QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
  197. } //*** CEnumIPAddresses::QueryInterface
  198. //////////////////////////////////////////////////////////////////////////////
  199. //
  200. // STDMETHODIMP_(ULONG)
  201. // CEnumIPAddresses::AddRef
  202. //
  203. //////////////////////////////////////////////////////////////////////////////
  204. STDMETHODIMP_( ULONG )
  205. CEnumIPAddresses::AddRef( void )
  206. {
  207. TraceFunc( "[IUnknown]" );
  208. InterlockedIncrement( &m_cRef );
  209. CRETURN( m_cRef );
  210. } //*** CEnumIPAddresses::AddRef
  211. //////////////////////////////////////////////////////////////////////////////
  212. //
  213. // STDMETHODIMP_(ULONG)
  214. // CEnumIPAddresses::Release
  215. //
  216. //////////////////////////////////////////////////////////////////////////////
  217. STDMETHODIMP_( ULONG )
  218. CEnumIPAddresses::Release( void )
  219. {
  220. TraceFunc( "[IUnknown]" );
  221. LONG cRef;
  222. cRef = InterlockedDecrement( &m_cRef );
  223. if ( cRef == 0 )
  224. {
  225. TraceDo( delete this );
  226. }
  227. CRETURN( cRef );
  228. } //*** CEnumIPAddresses::Release
  229. // ************************************************************************
  230. //
  231. // IExtendObjectManager
  232. //
  233. // ************************************************************************
  234. //////////////////////////////////////////////////////////////////////////////
  235. //
  236. // STDMETHODIMP
  237. // CEnumIPAddresses::FindObject(
  238. // OBJECTCOOKIE cookieIn
  239. // , REFCLSID rclsidTypeIn
  240. // , LPCWSTR pcszNameIn
  241. // , LPUNKNOWN * punkOut
  242. // )
  243. //
  244. //////////////////////////////////////////////////////////////////////////////
  245. STDMETHODIMP
  246. CEnumIPAddresses::FindObject(
  247. OBJECTCOOKIE cookieIn
  248. , REFCLSID rclsidTypeIn
  249. , LPCWSTR pcszNameIn
  250. , LPUNKNOWN * ppunkOut
  251. )
  252. {
  253. TraceFunc( "[IExtendObjectManager]" );
  254. OBJECTCOOKIE cookie;
  255. OBJECTCOOKIE cookieParent;
  256. IServiceProvider * psp;
  257. HRESULT hr = S_FALSE;
  258. IObjectManager * pom = NULL;
  259. IStandardInfo * psi = NULL;
  260. IEnumCookies * pec = NULL;
  261. DWORD cookieCount = 0;
  262. //
  263. // Check arguments
  264. //
  265. if ( cookieIn == 0 )
  266. {
  267. hr = THR( E_INVALIDARG );
  268. goto Cleanup;
  269. }
  270. if ( rclsidTypeIn != CLSID_IPAddressType )
  271. {
  272. hr = THR( E_INVALIDARG );
  273. goto Cleanup;
  274. }
  275. if ( ppunkOut == NULL )
  276. {
  277. hr = THR( E_POINTER );
  278. goto Cleanup;
  279. }
  280. AssertMsg( pcszNameIn == NULL, "Enums shouldn't have names." );
  281. //
  282. // Grab the object manager.
  283. //
  284. hr = THR( CoCreateInstance( CLSID_ServiceManager,
  285. NULL,
  286. CLSCTX_INPROC_SERVER,
  287. TypeSafeParams( IServiceProvider, &psp )
  288. ) );
  289. if ( FAILED( hr ) )
  290. {
  291. goto Cleanup;
  292. }
  293. hr = THR( psp->TypeSafeQS( CLSID_ObjectManager,
  294. IObjectManager,
  295. &pom
  296. ) );
  297. psp->Release(); // release promptly
  298. if ( FAILED( hr ) )
  299. {
  300. goto Cleanup;
  301. }
  302. //
  303. // Ask the Object Manager for information about our cookie so we can
  304. // get to the "parent" cookie.
  305. //
  306. hr = THR( pom->GetObject( DFGUID_StandardInfo,
  307. cookieIn,
  308. reinterpret_cast< IUnknown ** >( &psi )
  309. ) );
  310. if ( FAILED( hr ) )
  311. {
  312. goto Cleanup;
  313. }
  314. hr = STHR( psi->GetParent( &cookieParent ) );
  315. if ( FAILED( hr ) )
  316. {
  317. goto Cleanup;
  318. }
  319. //
  320. // Now ask the Object Manager for a cookie enumerator.
  321. //
  322. hr = THR( pom->FindObject( CLSID_IPAddressType,
  323. cookieParent,
  324. NULL,
  325. DFGUID_EnumCookies,
  326. NULL,
  327. reinterpret_cast< IUnknown ** >( &pec )
  328. ) );
  329. if ( FAILED( hr ) )
  330. {
  331. goto Cleanup;
  332. }
  333. pec = TraceInterface( L"CEnumIPAddresses!IEnumCookies", IEnumCookies, pec, 1 );
  334. //
  335. // Ask the enumerator how many cookies it has.
  336. //
  337. hr = THR( pec->Count( &cookieCount ) );
  338. if ( FAILED( hr ) )
  339. {
  340. goto Cleanup;
  341. }
  342. m_cAlloced = cookieCount;
  343. if ( m_cAlloced == 0 )
  344. {
  345. // The error text is better than the coding value.
  346. hr = HRESULT_FROM_WIN32( TW32( ERROR_NOT_FOUND ) );
  347. goto Cleanup;
  348. }
  349. //
  350. // Allocate a buffer to store the punks.
  351. //
  352. m_pList = (IClusCfgIPAddressInfo **) TraceAlloc( HEAP_ZERO_MEMORY, m_cAlloced * sizeof(IClusCfgIPAddressInfo *) );
  353. if ( m_pList == NULL )
  354. {
  355. hr = THR( E_OUTOFMEMORY );
  356. goto Cleanup;
  357. }
  358. //
  359. // Reset the enumerator.
  360. //
  361. hr = THR( pec->Reset() );
  362. if ( FAILED( hr ) )
  363. {
  364. goto Cleanup;
  365. }
  366. //
  367. // Now loop thru to collect the interfaces.
  368. //
  369. m_cIter = 0;
  370. while ( hr == S_OK && m_cIter < m_cAlloced )
  371. {
  372. hr = STHR( pec->Next( 1, &cookie, NULL ) );
  373. if ( FAILED( hr ) )
  374. {
  375. goto Cleanup;
  376. }
  377. if ( hr == S_FALSE )
  378. {
  379. break; // exit condition
  380. }
  381. hr = THR( pom->GetObject( DFGUID_IPAddressInfo,
  382. cookie,
  383. reinterpret_cast< IUnknown ** >( &m_pList[ m_cIter ] )
  384. ) );
  385. if ( FAILED( hr ) )
  386. {
  387. goto Cleanup;
  388. }
  389. m_cIter++;
  390. } // while: S_OK
  391. //
  392. // Reset the iter.
  393. //
  394. m_cIter = 0;
  395. //
  396. // Grab the interface.
  397. //
  398. hr = THR( QueryInterface( DFGUID_EnumIPAddressInfo,
  399. reinterpret_cast< void ** >( ppunkOut )
  400. ) );
  401. if ( FAILED( hr ) )
  402. {
  403. goto Cleanup;
  404. }
  405. Cleanup:
  406. if ( pom != NULL )
  407. {
  408. pom->Release();
  409. }
  410. if ( psi != NULL )
  411. {
  412. psi->Release();
  413. }
  414. if ( pec != NULL )
  415. {
  416. pec->Release();
  417. }
  418. HRETURN( hr );
  419. } //*** CEnumIPAddresses::FindObject
  420. //****************************************************************************
  421. //
  422. // IEnumClusCfgIPAddresses
  423. //
  424. //****************************************************************************
  425. //////////////////////////////////////////////////////////////////////////////
  426. //
  427. // STDMETHODIMP
  428. // CEnumIPAddresses::Next(
  429. // ULONG celt,
  430. // IClusCfgNode ** rgOut,
  431. // ULONG * pceltFetchedOut
  432. // )
  433. //
  434. //////////////////////////////////////////////////////////////////////////////
  435. STDMETHODIMP
  436. CEnumIPAddresses::Next(
  437. ULONG celt,
  438. IClusCfgIPAddressInfo * rgOut[],
  439. ULONG * pceltFetchedOut
  440. )
  441. {
  442. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  443. ULONG celtFetched;
  444. HRESULT hr = S_FALSE;
  445. //
  446. // Check parameters
  447. //
  448. if ( rgOut == NULL || celt == 0 )
  449. {
  450. hr = THR( E_POINTER );
  451. goto Cleanup;
  452. }
  453. //
  454. // Zero the return count.
  455. //
  456. if ( pceltFetchedOut != NULL )
  457. {
  458. *pceltFetchedOut = 0;
  459. }
  460. //
  461. // Clear the buffer
  462. //
  463. ZeroMemory( rgOut, celt * sizeof(rgOut[0]) );
  464. //
  465. // Loop thru copying the interfaces.
  466. //
  467. for( celtFetched = 0
  468. ; celtFetched + m_cIter < m_cAlloced && celtFetched < celt
  469. ; celtFetched ++
  470. )
  471. {
  472. hr = THR( m_pList[ m_cIter + celtFetched ]->TypeSafeQI( IClusCfgIPAddressInfo, &rgOut[ celtFetched ] ) );
  473. if ( FAILED( hr ) )
  474. {
  475. goto CleanupList;
  476. }
  477. rgOut[ celtFetched ] = TraceInterface( L"EnumIPAddresses!IClusCfgIPAddressInfo", IClusCfgIPAddressInfo, rgOut[ celtFetched ], 1 );
  478. } // for: celtFetched
  479. if ( pceltFetchedOut != NULL )
  480. {
  481. *pceltFetchedOut = celtFetched;
  482. }
  483. m_cIter += celtFetched;
  484. if ( celtFetched != celt )
  485. {
  486. hr = S_FALSE;
  487. }
  488. else
  489. {
  490. hr = S_OK;
  491. }
  492. Cleanup:
  493. HRETURN( hr );
  494. CleanupList:
  495. for ( ; celtFetched != 0 ; )
  496. {
  497. celtFetched --;
  498. rgOut[ celtFetched ]->Release();
  499. rgOut[ celtFetched ] = NULL;
  500. }
  501. goto Cleanup;
  502. } //*** CEnumIPAddresses::Next
  503. //////////////////////////////////////////////////////////////////////////////
  504. //
  505. // STDMETHODIMP
  506. // CEnumIPAddresses::Skip(
  507. // ULONG celt
  508. // )
  509. //
  510. //////////////////////////////////////////////////////////////////////////////
  511. STDMETHODIMP
  512. CEnumIPAddresses::Skip(
  513. ULONG celt
  514. )
  515. {
  516. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  517. HRESULT hr = S_OK;
  518. m_cIter += celt;
  519. if ( m_cIter > m_cAlloced )
  520. {
  521. m_cIter = m_cAlloced;
  522. hr = S_FALSE;
  523. }
  524. HRETURN( hr );
  525. } //*** CEnumIPAddresses::Skip
  526. //////////////////////////////////////////////////////////////////////////////
  527. //
  528. // STDMETHODIMP
  529. // CEnumIPAddresses::Reset( void )
  530. //
  531. //////////////////////////////////////////////////////////////////////////////
  532. STDMETHODIMP
  533. CEnumIPAddresses::Reset( void )
  534. {
  535. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  536. HRESULT hr = S_OK;
  537. m_cIter = 0;
  538. HRETURN( hr );
  539. } //*** CEnumIPAddresses::Reset
  540. //////////////////////////////////////////////////////////////////////////////
  541. //
  542. // STDMETHODIMP
  543. // CEnumIPAddresses::Clone(
  544. // IEnumClusCfgIPAddresses ** ppenumOut
  545. // )
  546. //
  547. //////////////////////////////////////////////////////////////////////////////
  548. STDMETHODIMP
  549. CEnumIPAddresses::Clone(
  550. IEnumClusCfgIPAddresses ** ppenumOut
  551. )
  552. {
  553. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  554. //
  555. // KB: not going to implement this method.
  556. //
  557. HRESULT hr = THR( E_NOTIMPL );
  558. HRETURN( hr );
  559. } //*** CEnumIPAddresses::Clone
  560. //////////////////////////////////////////////////////////////////////////////
  561. //
  562. // STDMETHODIMP
  563. // CEnumIPAddresses::Count(
  564. // DWORD * pnCountOut
  565. // )
  566. //
  567. //////////////////////////////////////////////////////////////////////////////
  568. STDMETHODIMP
  569. CEnumIPAddresses::Count(
  570. DWORD * pnCountOut
  571. )
  572. {
  573. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  574. HRESULT hr = S_OK;
  575. if ( pnCountOut == NULL )
  576. {
  577. hr = THR( E_POINTER );
  578. goto Cleanup;
  579. }
  580. *pnCountOut = m_cAlloced;
  581. Cleanup:
  582. HRETURN( hr );
  583. } //*** CEnumIPAddresses::Count