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.

654 lines
14 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. Assert( ppunkOut != NULL );
  39. HRESULT hr;
  40. CEnumIPAddresses * pemn = new CEnumIPAddresses;
  41. if ( pemn != NULL )
  42. {
  43. hr = THR( pemn->Init( ) );
  44. if ( SUCCEEDED( hr ) )
  45. {
  46. hr = THR( pemn->TypeSafeQI( IUnknown, ppunkOut ) );
  47. }
  48. pemn->Release( );
  49. }
  50. else
  51. {
  52. hr = E_OUTOFMEMORY;
  53. }
  54. HRETURN( hr );
  55. } // S_HrCreateInstance( )
  56. //////////////////////////////////////////////////////////////////////////////
  57. //
  58. // CEnumIPAddresses::CEnumIPAddresses( void )
  59. //
  60. //////////////////////////////////////////////////////////////////////////////
  61. CEnumIPAddresses::CEnumIPAddresses( void )
  62. {
  63. TraceFunc( "" );
  64. InterlockedIncrement( &g_cObjects );
  65. TraceFuncExit();
  66. } // CEnumIPAddresses( )
  67. //////////////////////////////////////////////////////////////////////////////
  68. //
  69. // STDMETHODIMP
  70. // CEnumIPAddresses::Init( void )
  71. //
  72. //////////////////////////////////////////////////////////////////////////////
  73. STDMETHODIMP
  74. CEnumIPAddresses::Init( void )
  75. {
  76. TraceFunc( "" );
  77. HRESULT hr = S_OK;
  78. // IUnknown stuff
  79. Assert( m_cRef == 0 );
  80. AddRef( ); // Add one count
  81. // IEnumClusCfgIPAddresses
  82. HRETURN( hr );
  83. } // Init( )
  84. //////////////////////////////////////////////////////////////////////////////
  85. //
  86. // CEnumIPAddresses::~CEnumIPAddresses( )
  87. //
  88. //////////////////////////////////////////////////////////////////////////////
  89. CEnumIPAddresses::~CEnumIPAddresses( )
  90. {
  91. TraceFunc( "" );
  92. if ( m_pList != NULL )
  93. {
  94. while ( m_cAlloced != 0 )
  95. {
  96. m_cAlloced --;
  97. (m_pList[ m_cAlloced ])->Release( );
  98. }
  99. }
  100. InterlockedDecrement( &g_cObjects );
  101. TraceFuncExit();
  102. } // ~CEnumIPAddresses( )
  103. // ************************************************************************
  104. //
  105. // IUnknown
  106. //
  107. // ************************************************************************
  108. //////////////////////////////////////////////////////////////////////////////
  109. //
  110. // STDMETHODIMP
  111. // CEnumIPAddresses::QueryInterface(
  112. // REFIID riid,
  113. // LPVOID *ppv
  114. // )
  115. //
  116. //////////////////////////////////////////////////////////////////////////////
  117. STDMETHODIMP
  118. CEnumIPAddresses::QueryInterface(
  119. REFIID riid,
  120. LPVOID *ppv
  121. )
  122. {
  123. TraceQIFunc( riid, ppv );
  124. HRESULT hr = E_NOINTERFACE;
  125. if ( IsEqualIID( riid, IID_IUnknown ) )
  126. {
  127. *ppv = static_cast< IEnumClusCfgIPAddresses * >( this );
  128. hr = S_OK;
  129. } // if: IUnknown
  130. else if ( IsEqualIID( riid, IID_IEnumClusCfgIPAddresses ) )
  131. {
  132. *ppv = TraceInterface( __THISCLASS__, IEnumClusCfgIPAddresses, this, 0 );
  133. hr = S_OK;
  134. } // else if: IEnumClusCfgIPAddresses
  135. else if ( IsEqualIID( riid, IID_IExtendObjectManager ) )
  136. {
  137. *ppv = TraceInterface( __THISCLASS__, IExtendObjectManager, this, 0 );
  138. hr = S_OK;
  139. } // else if: IExtendObjectManager
  140. if ( SUCCEEDED( hr ) )
  141. {
  142. ((IUnknown*) *ppv)->AddRef( );
  143. } // if: success
  144. QIRETURN_IGNORESTDMARSHALLING( hr, riid );
  145. } // QueryInterface( )
  146. //////////////////////////////////////////////////////////////////////////////
  147. //
  148. // STDMETHODIMP_(ULONG)
  149. // CEnumIPAddresses::AddRef( void )
  150. //
  151. //////////////////////////////////////////////////////////////////////////////
  152. STDMETHODIMP_(ULONG)
  153. CEnumIPAddresses::AddRef( void )
  154. {
  155. TraceFunc( "[IUnknown]" );
  156. InterlockedIncrement( &m_cRef );
  157. RETURN( m_cRef );
  158. } // AddRef( )
  159. //////////////////////////////////////////////////////////////////////////////
  160. //
  161. // STDMETHODIMP_(ULONG)
  162. // CEnumIPAddresses::Release( void )
  163. //
  164. //////////////////////////////////////////////////////////////////////////////
  165. STDMETHODIMP_(ULONG)
  166. CEnumIPAddresses::Release( void )
  167. {
  168. TraceFunc( "[IUnknown]" );
  169. InterlockedDecrement( &m_cRef );
  170. if ( m_cRef )
  171. RETURN( m_cRef );
  172. TraceDo( delete this );
  173. RETURN(0);
  174. } // Release( )
  175. // ************************************************************************
  176. //
  177. // IExtendObjectManager
  178. //
  179. // ************************************************************************
  180. //////////////////////////////////////////////////////////////////////////////
  181. //
  182. // STDMETHODIMP
  183. // CEnumIPAddresses::FindObject(
  184. // OBJECTCOOKIE cookieIn
  185. // , REFCLSID rclsidTypeIn
  186. // , LPCWSTR pcszNameIn
  187. // , LPUNKNOWN * punkOut
  188. // )
  189. //
  190. //////////////////////////////////////////////////////////////////////////////
  191. STDMETHODIMP
  192. CEnumIPAddresses::FindObject(
  193. OBJECTCOOKIE cookieIn
  194. , REFCLSID rclsidTypeIn
  195. , LPCWSTR pcszNameIn
  196. , LPUNKNOWN * ppunkOut
  197. )
  198. {
  199. TraceFunc( "[IExtendObjectManager]" );
  200. OBJECTCOOKIE cookie;
  201. OBJECTCOOKIE cookieParent;
  202. IServiceProvider * psp;
  203. HRESULT hr = E_UNEXPECTED;
  204. IObjectManager * pom = NULL;
  205. IStandardInfo * psi = NULL;
  206. IEnumCookies * pec = NULL;
  207. DWORD cookieCount = 0;
  208. //
  209. // Check arguments
  210. //
  211. if ( cookieIn == 0 )
  212. goto InvalidArg;
  213. if ( rclsidTypeIn != CLSID_IPAddressType )
  214. goto InvalidType;
  215. if ( ppunkOut == NULL )
  216. goto InvalidPointer;
  217. AssertMsg( pcszNameIn == NULL, "Enums shouldn't have names." );
  218. //
  219. // Grab the object manager.
  220. //
  221. hr = THR( CoCreateInstance( CLSID_ServiceManager,
  222. NULL,
  223. CLSCTX_INPROC_SERVER,
  224. TypeSafeParams( IServiceProvider, &psp )
  225. ) );
  226. if ( FAILED( hr ) )
  227. goto Cleanup;
  228. hr = THR( psp->TypeSafeQS( CLSID_ObjectManager,
  229. IObjectManager,
  230. &pom
  231. ) );
  232. psp->Release( ); // release promptly
  233. if ( FAILED( hr ) )
  234. goto Cleanup;
  235. //
  236. // Ask the Object Manager for information about our cookie so we can
  237. // get to the "parent" cookie.
  238. //
  239. hr = THR( pom->GetObject( DFGUID_StandardInfo,
  240. cookieIn,
  241. reinterpret_cast< IUnknown ** >( &psi )
  242. ) );
  243. if ( FAILED( hr ) )
  244. goto Cleanup;
  245. hr = STHR( psi->GetParent( &cookieParent ) );
  246. if ( FAILED( hr ) )
  247. goto Cleanup;
  248. //
  249. // Now ask the Object Manager for a cookie enumerator.
  250. //
  251. hr = THR( pom->FindObject( CLSID_IPAddressType,
  252. cookieParent,
  253. NULL,
  254. DFGUID_EnumCookies,
  255. NULL,
  256. reinterpret_cast< IUnknown ** >( &pec )
  257. ) );
  258. if ( FAILED( hr ) )
  259. goto Cleanup;
  260. pec = TraceInterface( L"CEnumIPAddresses!IEnumCookies", IEnumCookies, pec, 1 );
  261. //
  262. // Ask the enumerator how many cookies it has.
  263. //
  264. hr = THR( pec->Count( &cookieCount ) );
  265. if ( FAILED( hr ) )
  266. goto Cleanup;
  267. m_cAlloced = cookieCount;
  268. if ( m_cAlloced == 0 )
  269. goto ErrorNotFound;
  270. //
  271. // Allocate a buffer to store the punks.
  272. //
  273. m_pList = (IClusCfgIPAddressInfo **) TraceAlloc( HEAP_ZERO_MEMORY, m_cAlloced * sizeof(IClusCfgIPAddressInfo *) );
  274. if ( m_pList == NULL )
  275. goto OutOfMemory;
  276. //
  277. // Reset the enumerator.
  278. //
  279. hr = THR( pec->Reset( ) );
  280. if ( FAILED( hr ) )
  281. goto Cleanup;
  282. //
  283. // Now loop thru to collect the interfaces.
  284. //
  285. m_cIter = 0;
  286. while ( hr == S_OK && m_cIter < m_cAlloced )
  287. {
  288. hr = STHR( pec->Next( 1, &cookie, NULL ) );
  289. if ( FAILED( hr ) )
  290. goto Cleanup;
  291. if ( hr == S_FALSE )
  292. break; // exit condition
  293. hr = THR( pom->GetObject( DFGUID_IPAddressInfo,
  294. cookie,
  295. reinterpret_cast< IUnknown ** >( &m_pList[ m_cIter ] )
  296. ) );
  297. if ( FAILED( hr ) )
  298. goto Cleanup;
  299. m_cIter++;
  300. } // while: S_OK
  301. //
  302. // Reset the iter.
  303. //
  304. m_cIter = 0;
  305. //
  306. // Grab the interface.
  307. //
  308. hr = THR( QueryInterface( DFGUID_EnumIPAddressInfo,
  309. reinterpret_cast< void ** >( ppunkOut )
  310. ) );
  311. if ( FAILED( hr ) )
  312. goto Cleanup;
  313. Cleanup:
  314. if ( pom != NULL )
  315. {
  316. pom->Release( );
  317. }
  318. if ( psi != NULL )
  319. {
  320. psi->Release( );
  321. }
  322. if ( pec != NULL )
  323. {
  324. pec->Release( );
  325. }
  326. HRETURN( hr );
  327. InvalidArg:
  328. hr = THR( E_INVALIDARG );
  329. goto Cleanup;
  330. InvalidPointer:
  331. hr = THR( E_POINTER );
  332. goto Cleanup;
  333. InvalidType:
  334. //
  335. // TODO: gpease 07-APR-2000
  336. // Come up with a better error code.
  337. //
  338. hr = THR( E_FAIL );
  339. goto Cleanup;
  340. ErrorNotFound:
  341. // The error text is better than the coding value.
  342. hr = THR( HRESULT_FROM_WIN32( ERROR_NOT_FOUND ) );
  343. goto Cleanup;
  344. OutOfMemory:
  345. hr = E_OUTOFMEMORY;
  346. goto Cleanup;
  347. } // FindObject( )
  348. //****************************************************************************
  349. //
  350. // IEnumClusCfgIPAddresses
  351. //
  352. //****************************************************************************
  353. //////////////////////////////////////////////////////////////////////////////
  354. //
  355. // STDMETHODIMP
  356. // CEnumIPAddresses::Next(
  357. // ULONG celt,
  358. // IClusCfgNode ** rgOut,
  359. // ULONG * pceltFetchedOut
  360. // )
  361. //
  362. //////////////////////////////////////////////////////////////////////////////
  363. STDMETHODIMP
  364. CEnumIPAddresses::Next(
  365. ULONG celt,
  366. IClusCfgIPAddressInfo * rgOut[],
  367. ULONG * pceltFetchedOut
  368. )
  369. {
  370. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  371. ULONG celtFetched;
  372. HRESULT hr = E_UNEXPECTED;
  373. //
  374. // Check parameters
  375. //
  376. if ( rgOut == NULL || celt == 0 )
  377. goto InvalidPointer;
  378. //
  379. // Zero the return count.
  380. //
  381. if ( pceltFetchedOut != NULL )
  382. {
  383. *pceltFetchedOut = 0;
  384. }
  385. //
  386. // Clear the buffer
  387. //
  388. ZeroMemory( rgOut, celt * sizeof(rgOut[0]) );
  389. //
  390. // Loop thru copying the interfaces.
  391. //
  392. for( celtFetched = 0
  393. ; celtFetched + m_cIter < m_cAlloced && celtFetched < celt
  394. ; celtFetched ++
  395. )
  396. {
  397. hr = THR( m_pList[ m_cIter + celtFetched ]->TypeSafeQI( IClusCfgIPAddressInfo, &rgOut[ celtFetched ] ) );
  398. if ( FAILED( hr ) )
  399. goto CleanupList;
  400. rgOut[ celtFetched ] = TraceInterface( L"EnumIPAddresses!IClusCfgIPAddressInfo", IClusCfgIPAddressInfo, rgOut[ celtFetched ], 1 );
  401. } // for: celtFetched
  402. if ( pceltFetchedOut != NULL )
  403. {
  404. *pceltFetchedOut = celtFetched;
  405. }
  406. m_cIter += celtFetched;
  407. if ( celtFetched != celt )
  408. {
  409. hr = S_FALSE;
  410. }
  411. else
  412. {
  413. hr = S_OK;
  414. }
  415. Cleanup:
  416. HRETURN( hr );
  417. CleanupList:
  418. for ( ; celtFetched != 0 ; )
  419. {
  420. celtFetched --;
  421. rgOut[ celtFetched ]->Release( );
  422. rgOut[ celtFetched ] = NULL;
  423. }
  424. goto Cleanup;
  425. InvalidPointer:
  426. hr = THR( E_POINTER );
  427. goto Cleanup;
  428. } // Next( )
  429. //////////////////////////////////////////////////////////////////////////////
  430. //
  431. // STDMETHODIMP
  432. // CEnumIPAddresses::Skip(
  433. // ULONG celt
  434. // )
  435. //
  436. //////////////////////////////////////////////////////////////////////////////
  437. STDMETHODIMP
  438. CEnumIPAddresses::Skip(
  439. ULONG celt
  440. )
  441. {
  442. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  443. HRESULT hr = S_OK;
  444. m_cIter += celt;
  445. if ( m_cIter > m_cAlloced )
  446. {
  447. m_cIter = m_cAlloced;
  448. hr = S_FALSE;
  449. }
  450. HRETURN( hr );
  451. } // Skip( )
  452. //////////////////////////////////////////////////////////////////////////////
  453. //
  454. // STDMETHODIMP
  455. // CEnumIPAddresses::Reset( void )
  456. //
  457. //////////////////////////////////////////////////////////////////////////////
  458. STDMETHODIMP
  459. CEnumIPAddresses::Reset( void )
  460. {
  461. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  462. HRESULT hr = S_OK;
  463. m_cIter = 0;
  464. HRETURN( hr );
  465. } // Reset( )
  466. //////////////////////////////////////////////////////////////////////////////
  467. //
  468. // STDMETHODIMP
  469. // CEnumIPAddresses::Clone(
  470. // IEnumClusCfgIPAddresses ** ppenumOut
  471. // )
  472. //
  473. //////////////////////////////////////////////////////////////////////////////
  474. STDMETHODIMP
  475. CEnumIPAddresses::Clone(
  476. IEnumClusCfgIPAddresses ** ppenumOut
  477. )
  478. {
  479. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  480. //
  481. // KB: not going to implement this method.
  482. //
  483. HRESULT hr = THR( E_NOTIMPL );
  484. HRETURN( hr );
  485. } // Clone( )
  486. //////////////////////////////////////////////////////////////////////////////
  487. //
  488. // STDMETHODIMP
  489. // CEnumIPAddresses::Count(
  490. // DWORD * pnCountOut
  491. // )
  492. //
  493. //////////////////////////////////////////////////////////////////////////////
  494. STDMETHODIMP
  495. CEnumIPAddresses::Count(
  496. DWORD * pnCountOut
  497. )
  498. {
  499. TraceFunc( "[IEnumClusCfgIPAddresses]" );
  500. HRESULT hr = S_OK;
  501. if ( pnCountOut == NULL )
  502. {
  503. hr = THR( E_POINTER );
  504. goto Cleanup;
  505. }
  506. *pnCountOut = m_cAlloced;
  507. Cleanup:
  508. HRETURN( hr );
  509. }// Count( )