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.

727 lines
16 KiB

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