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.

1217 lines
29 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ObjectManager.cpp
  7. //
  8. // Description:
  9. // Object Manager implementation.
  10. //
  11. // Documentation:
  12. // Yes.
  13. //
  14. // Maintained By:
  15. // Galen Barbee (GalenB) 22-NOV-1999
  16. //
  17. //////////////////////////////////////////////////////////////////////////////
  18. #include "pch.h"
  19. #include "ObjectManager.h"
  20. #include "ConnectionInfo.h"
  21. #include "StandardInfo.h"
  22. #include "EnumCookies.h"
  23. DEFINE_THISCLASS("CObjectManager")
  24. #define COOKIE_BUFFER_GROW_SIZE 100
  25. // ************************************************************************
  26. //
  27. // Constructor / Destructor
  28. //
  29. // ************************************************************************
  30. //////////////////////////////////////////////////////////////////////////////
  31. //
  32. // LPUNKNOWN
  33. // CObjectManager::S_HrCreateInstance(
  34. // IUnknown ** ppunkOut
  35. // )
  36. //
  37. //////////////////////////////////////////////////////////////////////////////
  38. HRESULT
  39. CObjectManager::S_HrCreateInstance(
  40. IUnknown ** ppunkOut
  41. )
  42. {
  43. TraceFunc( "" );
  44. Assert( ppunkOut != NULL );
  45. HRESULT hr;
  46. IServiceProvider * psp;
  47. // Don't wrap - this can fail with E_POINTER.
  48. hr = CServiceManager::S_HrGetManagerPointer( &psp );
  49. if ( SUCCEEDED( hr ) )
  50. {
  51. hr = THR( psp->TypeSafeQS( CLSID_ObjectManager,
  52. IUnknown,
  53. ppunkOut
  54. ) );
  55. psp->Release( );
  56. } // if: service manager
  57. else if ( hr == E_POINTER )
  58. {
  59. //
  60. // This happens when the Service Manager is first started.
  61. //
  62. CObjectManager * pom = new CObjectManager( );
  63. if ( pom != NULL )
  64. {
  65. hr = THR( pom->Init( ) );
  66. if ( SUCCEEDED( hr ) )
  67. {
  68. hr = THR( pom->TypeSafeQI( IUnknown, ppunkOut ) );
  69. } // if: success
  70. pom->Release( );
  71. } // if: got object
  72. else
  73. {
  74. hr = E_OUTOFMEMORY;
  75. }
  76. } // if: service manager doesn't exists
  77. else
  78. {
  79. THR( hr );
  80. } // else:
  81. HRETURN( hr );
  82. } // S_HrCreateInstance( )
  83. //////////////////////////////////////////////////////////////////////////////
  84. //
  85. // CObjectManager::CObjectManager( void )
  86. //
  87. //////////////////////////////////////////////////////////////////////////////
  88. CObjectManager::CObjectManager( void )
  89. {
  90. TraceFunc( "" );
  91. InterlockedIncrement( &g_cObjects );
  92. TraceFuncExit();
  93. } // CObjectManager( )
  94. //////////////////////////////////////////////////////////////////////////////
  95. //
  96. // STDMETHODIMP
  97. // CObjectManager::Init( void )
  98. //
  99. //////////////////////////////////////////////////////////////////////////////
  100. STDMETHODIMP
  101. CObjectManager::Init( void )
  102. {
  103. TraceFunc( "" );
  104. HRESULT hr = S_OK;
  105. // IUnknown stuff
  106. Assert( m_cRef == 0 );
  107. AddRef( ); // Add one count
  108. // IObjectManager
  109. Assert( m_cAllocSize == 0 );
  110. Assert( m_cCurrentUsed == 0 );
  111. Assert( m_pCookies == NULL );
  112. HRETURN( hr );
  113. } // Init( )
  114. //////////////////////////////////////////////////////////////////////////////
  115. //
  116. // CObjectManager::~CObjectManager( )
  117. //
  118. //////////////////////////////////////////////////////////////////////////////
  119. CObjectManager::~CObjectManager( )
  120. {
  121. TraceFunc( "" );
  122. if ( m_pCookies != NULL )
  123. {
  124. while ( m_cCurrentUsed != 0 )
  125. {
  126. m_cCurrentUsed --;
  127. if ( m_pCookies[ m_cCurrentUsed ] != NULL )
  128. {
  129. m_pCookies[ m_cCurrentUsed ]->Release( );
  130. }
  131. }
  132. TraceFree( m_pCookies );
  133. }
  134. InterlockedDecrement( &g_cObjects );
  135. TraceFuncExit();
  136. } // ~CObjectManager( )
  137. // ************************************************************************
  138. //
  139. // IUnknown
  140. //
  141. // ************************************************************************
  142. //////////////////////////////////////////////////////////////////////////////
  143. //
  144. // STDMETHODIMP
  145. // CObjectManager::QueryInterface(
  146. // REFIID riid,
  147. // LPVOID *ppv
  148. // )
  149. //
  150. //////////////////////////////////////////////////////////////////////////////
  151. STDMETHODIMP
  152. CObjectManager::QueryInterface(
  153. REFIID riid,
  154. LPVOID *ppv
  155. )
  156. {
  157. TraceQIFunc( riid, ppv );
  158. HRESULT hr = E_NOINTERFACE;
  159. if ( IsEqualIID( riid, IID_IUnknown ) )
  160. {
  161. *ppv = static_cast< LPUNKNOWN >( this );
  162. hr = S_OK;
  163. } // if: IUnknown
  164. else if ( IsEqualIID( riid, IID_IObjectManager ) )
  165. {
  166. *ppv = TraceInterface( __THISCLASS__, IObjectManager, this, 0 );
  167. hr = S_OK;
  168. } // else if: IObjectManager
  169. if ( SUCCEEDED( hr ) )
  170. {
  171. ((IUnknown*) *ppv)->AddRef( );
  172. } // if: success
  173. QIRETURN_IGNORESTDMARSHALLING( hr, riid );
  174. }
  175. //////////////////////////////////////////////////////////////////////////////
  176. //
  177. // STDMETHODIMP_(ULONG)
  178. // CObjectManager::AddRef( void )
  179. //
  180. //////////////////////////////////////////////////////////////////////////////
  181. STDMETHODIMP_(ULONG)
  182. CObjectManager::AddRef( void )
  183. {
  184. TraceFunc( "[IUnknown]" );
  185. InterlockedIncrement( &m_cRef );
  186. RETURN( m_cRef );
  187. } // AddRef( )
  188. //////////////////////////////////////////////////////////////////////////////
  189. //
  190. // STDMETHODIMP_(ULONG)
  191. // CObjectManager::Release( void )
  192. //
  193. //////////////////////////////////////////////////////////////////////////////
  194. STDMETHODIMP_(ULONG)
  195. CObjectManager::Release( void )
  196. {
  197. TraceFunc( "[IUnknown]" );
  198. InterlockedDecrement( &m_cRef );
  199. if ( m_cRef )
  200. RETURN( m_cRef );
  201. TraceDo( delete this );
  202. RETURN(0);
  203. } // Release( )
  204. // ************************************************************************
  205. //
  206. // IObjectManager
  207. //
  208. // ************************************************************************
  209. //////////////////////////////////////////////////////////////////////////////
  210. //
  211. // STDMETHODIMP
  212. // CObjectManager::FindObject(
  213. // REFCLSID rclsidTypeIn,
  214. // OBJECTCOOKIE cookieParentIn,
  215. // LPCWSTR pcszNameIn,
  216. // REFCLSID rclsidFormatIn,
  217. // OBJECTCOOKIE * cookieOut,
  218. // LPUNKNOWN * punkOut
  219. // )
  220. //
  221. //////////////////////////////////////////////////////////////////////////////
  222. STDMETHODIMP
  223. CObjectManager::FindObject(
  224. REFCLSID rclsidTypeIn,
  225. OBJECTCOOKIE cookieParentIn,
  226. LPCWSTR pcszNameIn,
  227. REFCLSID rclsidFormatIn,
  228. OBJECTCOOKIE * pcookieOut,
  229. LPUNKNOWN * ppunkOut
  230. )
  231. {
  232. TraceFunc( "[IObjectManager]" );
  233. ExtObjectEntry * pentry;
  234. HRESULT hr = E_UNEXPECTED;
  235. OBJECTCOOKIE cookie = 0;
  236. CStandardInfo * pcsi = NULL; // don't free
  237. BOOL fTempCookie = FALSE;
  238. CEnumCookies * pcec = NULL;
  239. IUnknown * punk = NULL;
  240. IExtendObjectManager * peom = NULL;
  241. //
  242. // Check to see if we already have an object.
  243. //
  244. if ( pcszNameIn != NULL )
  245. {
  246. hr = STHR( HrSearchForExistingCookie( rclsidTypeIn, cookieParentIn, pcszNameIn, &cookie ) );
  247. if ( FAILED( hr ) )
  248. goto Cleanup;
  249. if ( hr == S_FALSE )
  250. {
  251. hr = THR( HrCreateNewCookie( rclsidTypeIn, cookieParentIn, pcszNameIn, &cookie ) );
  252. if ( FAILED( hr ) )
  253. goto Cleanup;
  254. pcsi = m_pCookies[ cookie ];
  255. Assert( pcsi != NULL );
  256. }
  257. else if ( hr == S_OK )
  258. {
  259. //
  260. // Found an existing cookie.
  261. //
  262. if ( pcookieOut != NULL )
  263. {
  264. *pcookieOut = cookie;
  265. }
  266. if ( ppunkOut != NULL )
  267. {
  268. pcsi = m_pCookies[ cookie ];
  269. //
  270. // Is the object still in an failed state or still pending?
  271. //
  272. if ( FAILED( pcsi->m_hrStatus ) )
  273. {
  274. hr = pcsi->m_hrStatus;
  275. goto Cleanup;
  276. }
  277. //
  278. // Retrieve the requested format.
  279. //
  280. hr = THR( GetObject( rclsidFormatIn, cookie, ppunkOut ) );
  281. // we always jump to cleanup. No need to check hr here.
  282. goto Cleanup;
  283. }
  284. }
  285. else
  286. {
  287. //
  288. // Unexpected error_success - now what?
  289. //
  290. Assert( !hr );
  291. goto Cleanup;
  292. }
  293. } // if: named object
  294. else
  295. {
  296. Assert( pcsi == NULL );
  297. }
  298. //
  299. // Create a new object.
  300. //
  301. if ( IsEqualIID( rclsidFormatIn, IID_NULL )
  302. || ppunkOut == NULL
  303. )
  304. {
  305. //
  306. // No-op.
  307. //
  308. hr = S_OK;
  309. }
  310. else if ( IsEqualIID( rclsidFormatIn, DFGUID_StandardInfo ) )
  311. {
  312. hr = THR( pcsi->QueryInterface( DFGUID_StandardInfo,
  313. reinterpret_cast< void ** >( ppunkOut )
  314. ) );
  315. if ( FAILED( hr ) )
  316. goto Cleanup;
  317. }
  318. else if ( IsEqualIID( rclsidFormatIn, DFGUID_ConnectionInfoFormat ) )
  319. {
  320. if ( pcsi->m_pci != NULL )
  321. {
  322. *ppunkOut = TraceInterface( L"CConnectionInfo!ObjectManager", IConnectionInfo, pcsi->m_pci, 0 );
  323. (*ppunkOut)->AddRef( );
  324. hr = S_OK;
  325. }
  326. else
  327. {
  328. hr = THR( CConnectionInfo::S_HrCreateInstance( &punk,
  329. pcsi->m_cookieParent
  330. ) );
  331. if ( FAILED( hr ) )
  332. goto Cleanup;
  333. hr = THR( punk->TypeSafeQI( IConnectionInfo,
  334. &pcsi->m_pci
  335. ) );
  336. if ( FAILED( hr ) )
  337. goto Cleanup;
  338. hr = THR( punk->QueryInterface( IID_IConnectionInfo,
  339. reinterpret_cast< void ** >( ppunkOut )
  340. ) );
  341. if ( FAILED( hr ) )
  342. goto Cleanup;
  343. }
  344. }
  345. else if ( IsEqualIID( rclsidFormatIn, DFGUID_EnumCookies ) )
  346. {
  347. ULONG cIter;
  348. //
  349. // Create a new cookie enumerator.
  350. //
  351. pcec = new CEnumCookies;
  352. if ( pcec == NULL )
  353. goto OutOfMemory;
  354. //
  355. // Initialize the enumerator. This also cause an AddRef( ).
  356. //
  357. hr = THR( pcec->Init( ) );
  358. if ( FAILED( hr ) )
  359. goto Cleanup;
  360. //
  361. // See who matches our citeria.
  362. //
  363. pcec->m_cIter = 0;
  364. for( cIter = 1; cIter < m_cCurrentUsed; cIter ++ )
  365. {
  366. pcsi = m_pCookies[ cIter ];
  367. if ( pcsi != NULL )
  368. {
  369. if ( rclsidTypeIn == IID_NULL
  370. || pcsi->m_clsidType == rclsidTypeIn
  371. )
  372. {
  373. if ( cookieParentIn == NULL
  374. || pcsi->m_cookieParent == cookieParentIn
  375. )
  376. {
  377. if ( ( pcszNameIn == NULL )
  378. || ( ( pcsi->m_bstrName != NULL )
  379. && ( StrCmpI( pcsi->m_bstrName, pcszNameIn ) == 0 )
  380. )
  381. )
  382. {
  383. //
  384. // Match!
  385. //
  386. pcec->m_cIter ++;
  387. } // if: names match
  388. } // if: parents match
  389. } // if: match parent and type
  390. } // if: valid element
  391. } // for: cIter
  392. if ( pcec->m_cIter == 0 )
  393. goto ErrorNotFound;
  394. //
  395. // Alloc an array to hold the cookies.
  396. //
  397. pcec->m_pList = (OBJECTCOOKIE*) TraceAlloc( HEAP_ZERO_MEMORY, pcec->m_cIter * sizeof(OBJECTCOOKIE) );
  398. if ( pcec->m_pList == NULL )
  399. goto OutOfMemory;
  400. pcec->m_cAlloced = pcec->m_cIter;
  401. pcec->m_cIter = 0;
  402. for( cIter = 1; cIter < m_cCurrentUsed; cIter ++ )
  403. {
  404. pcsi = m_pCookies[ cIter ];
  405. if ( pcsi != NULL )
  406. {
  407. if ( rclsidTypeIn == IID_NULL
  408. || pcsi->m_clsidType == rclsidTypeIn
  409. )
  410. {
  411. if ( cookieParentIn == NULL
  412. || pcsi->m_cookieParent == cookieParentIn
  413. )
  414. {
  415. if ( ( pcszNameIn == NULL )
  416. || ( ( pcsi->m_bstrName != NULL )
  417. && ( StrCmpI( pcsi->m_bstrName, pcszNameIn ) == 0 )
  418. )
  419. )
  420. {
  421. //
  422. // Match!
  423. //
  424. pcec->m_pList[ pcec->m_cIter ] = cIter;
  425. pcec->m_cIter ++;
  426. } // if: names match
  427. } // if: parents match
  428. } // if: match parent and type
  429. } // if: valid element
  430. } // for: cIter
  431. Assert( pcec->m_cIter != 0 );
  432. pcec->m_cCookies = pcec->m_cIter;
  433. pcec->m_cIter = 0;
  434. //
  435. // Grab the inteface on the way out.
  436. //
  437. hr = THR( pcec->QueryInterface( IID_IEnumCookies,
  438. reinterpret_cast< void ** >( ppunkOut )
  439. ) );
  440. if ( FAILED( hr ) )
  441. goto Cleanup;
  442. }
  443. else
  444. {
  445. //
  446. // Check for extension formats.
  447. //
  448. //
  449. // See if the format already exists for this cookie.
  450. //
  451. if ( punk != NULL )
  452. {
  453. punk->Release( );
  454. punk = NULL;
  455. }
  456. if ( pcsi != NULL )
  457. {
  458. for( pentry = pcsi->m_pExtObjList; pentry != NULL; pentry = pentry->pNext )
  459. {
  460. if ( pentry->iid == rclsidFormatIn )
  461. {
  462. hr = THR( pentry->punk->QueryInterface( rclsidFormatIn,
  463. reinterpret_cast< void ** >( &punk )
  464. ) );
  465. if ( FAILED( hr ) )
  466. goto Cleanup;
  467. break; // exit loop
  468. }
  469. } // for: pentry
  470. } // if: have cookie
  471. else
  472. {
  473. //
  474. // Create a temporary cookie.
  475. //
  476. Assert( pcszNameIn == NULL );
  477. hr = THR( HrCreateNewCookie( IID_NULL, cookieParentIn, NULL, &cookie ) );
  478. if ( FAILED( hr ) )
  479. goto Cleanup;
  480. fTempCookie = TRUE;
  481. Assert( pcsi == NULL );
  482. } // else: need a temporary cookie
  483. if ( punk == NULL )
  484. {
  485. //
  486. // Possibly a new or externally object, try creating it and querying.
  487. //
  488. hr = THR( HrCoCreateInternalInstance( rclsidFormatIn,
  489. NULL,
  490. CLSCTX_ALL,
  491. TypeSafeParams( IExtendObjectManager, &peom )
  492. ) );
  493. if ( FAILED( hr ) )
  494. goto Cleanup;
  495. Assert( punk == NULL );
  496. // Can't wrap with THR because it can return E_PENDING.
  497. hr = peom->FindObject( cookie,
  498. rclsidTypeIn,
  499. pcszNameIn,
  500. &punk
  501. );
  502. if ( hr == E_PENDING )
  503. {
  504. // ignore
  505. }
  506. else if ( FAILED( hr ) )
  507. {
  508. THR( hr );
  509. goto Cleanup;
  510. }
  511. if ( fTempCookie )
  512. {
  513. (m_pCookies[ cookie ])->Release( );
  514. m_pCookies[ cookie ] = NULL;
  515. }
  516. else
  517. {
  518. //
  519. // Keep track of the format (if extension wants)
  520. //
  521. if ( ( ( SUCCEEDED( hr )
  522. && hr != S_FALSE
  523. )
  524. || hr == E_PENDING
  525. )
  526. && punk != NULL
  527. && pcsi != NULL
  528. )
  529. {
  530. pentry = (ExtObjectEntry *) TraceAlloc( 0, sizeof(ExtObjectEntry) );
  531. if ( pentry == NULL )
  532. goto OutOfMemory;
  533. pentry->iid = rclsidFormatIn;
  534. pentry->pNext = pcsi->m_pExtObjList;
  535. pentry->punk = punk;
  536. pentry->punk->AddRef( );
  537. pcsi->m_pExtObjList = pentry; // update header of list (LIFO)
  538. pcsi->m_hrStatus = hr; // update status
  539. }
  540. } // else: persistent cookie
  541. if ( SUCCEEDED( hr ) )
  542. {
  543. // Give up ownership
  544. *ppunkOut = punk;
  545. punk = NULL;
  546. }
  547. } // if: creating new object
  548. } // else: possible extension format
  549. //
  550. // Save stuff for the caller.
  551. //
  552. if ( pcookieOut != NULL )
  553. {
  554. *pcookieOut = cookie;
  555. }
  556. Cleanup:
  557. if ( punk != NULL )
  558. {
  559. punk->Release( );
  560. }
  561. if ( peom != NULL )
  562. {
  563. peom->Release( );
  564. }
  565. if ( pcec != NULL )
  566. {
  567. pcec->Release( );
  568. }
  569. HRETURN( hr );
  570. OutOfMemory:
  571. hr = E_OUTOFMEMORY;
  572. goto Cleanup;
  573. ErrorNotFound:
  574. // The error text is better than the coding value.
  575. hr = THR( HRESULT_FROM_WIN32( ERROR_NOT_FOUND ) );
  576. goto Cleanup;
  577. } // FindObject( )
  578. //////////////////////////////////////////////////////////////////////////////
  579. //
  580. // STDMETHODIMP
  581. // CObjectManager::GetObject(
  582. // REFCLSID rclsidFormatIn,
  583. // OBJECTCOOKIE cookieIn,
  584. // LPUNKNOWN * ppunkOut
  585. // )
  586. //
  587. //////////////////////////////////////////////////////////////////////////////
  588. STDMETHODIMP
  589. CObjectManager::GetObject(
  590. REFCLSID rclsidFormatIn,
  591. OBJECTCOOKIE cookieIn,
  592. LPUNKNOWN * ppunkOut
  593. )
  594. {
  595. TraceFunc( "[IObjectManager]" );
  596. CStandardInfo * pcsi;
  597. ExtObjectEntry * pentry;
  598. HRESULT hr = E_UNEXPECTED;
  599. IUnknown * punk = NULL;
  600. IExtendObjectManager * peom = NULL;
  601. //
  602. // Check parameters
  603. //
  604. if ( cookieIn == 0 || cookieIn >= m_cCurrentUsed )
  605. goto InvalidArg;
  606. pcsi = m_pCookies[ cookieIn ];
  607. if ( pcsi == NULL )
  608. goto ErrorNotFound;
  609. //
  610. // Create the request format object.
  611. //
  612. if ( IsEqualIID( rclsidFormatIn, IID_NULL )
  613. || ppunkOut == NULL
  614. )
  615. {
  616. //
  617. // No-op.
  618. //
  619. hr = S_OK;
  620. }
  621. else if ( IsEqualIID( rclsidFormatIn, DFGUID_StandardInfo ) )
  622. {
  623. hr = THR( pcsi->QueryInterface( DFGUID_StandardInfo,
  624. reinterpret_cast< void ** >( ppunkOut )
  625. ) );
  626. if ( FAILED( hr ) )
  627. goto Cleanup;
  628. }
  629. else if ( IsEqualIID( rclsidFormatIn, DFGUID_ConnectionInfoFormat ) )
  630. {
  631. if ( pcsi->m_pci != NULL )
  632. {
  633. *ppunkOut = pcsi->m_pci;
  634. (*ppunkOut)->AddRef( );
  635. hr = S_OK;
  636. }
  637. else
  638. {
  639. hr = THR( CConnectionInfo::S_HrCreateInstance( &punk,
  640. pcsi->m_cookieParent
  641. ) );
  642. if ( FAILED( hr ) )
  643. goto Cleanup;
  644. hr = THR( punk->TypeSafeQI( IConnectionInfo,
  645. &pcsi->m_pci
  646. ) );
  647. if ( FAILED( hr ) )
  648. goto Cleanup;
  649. hr = THR( punk->QueryInterface( IID_IConnectionInfo,
  650. reinterpret_cast< void ** >( ppunkOut )
  651. ) );
  652. if ( FAILED( hr ) )
  653. goto Cleanup;
  654. }
  655. }
  656. else
  657. {
  658. //
  659. // See if the format already exists for this cookie.
  660. //
  661. if ( punk != NULL )
  662. {
  663. punk->Release( );
  664. punk = NULL;
  665. }
  666. for( pentry = pcsi->m_pExtObjList; pentry != NULL; pentry = pentry->pNext )
  667. {
  668. if ( pentry->iid == rclsidFormatIn )
  669. {
  670. hr = THR( pentry->punk->QueryInterface( rclsidFormatIn,
  671. reinterpret_cast< void ** >( &punk )
  672. ) );
  673. if ( FAILED( hr ) )
  674. goto Cleanup;
  675. break; // exit loop
  676. }
  677. } // for: pentry
  678. if ( punk == NULL )
  679. goto ErrorNotFound;
  680. // Give up ownership
  681. *ppunkOut = punk;
  682. punk = NULL;
  683. } // else: external?
  684. Cleanup:
  685. if ( punk != NULL )
  686. {
  687. punk->Release( );
  688. }
  689. if ( peom != NULL )
  690. {
  691. peom->Release( );
  692. }
  693. HRETURN( hr );
  694. InvalidArg:
  695. hr = THR( E_INVALIDARG );
  696. goto Cleanup;
  697. ErrorNotFound:
  698. hr = THR( HRESULT_FROM_WIN32( ERROR_NOT_FOUND ) );
  699. goto Cleanup;
  700. #if 0
  701. OutOfMemory:
  702. hr = E_OUTOFMEMORY;
  703. goto Cleanup;
  704. #endif
  705. } // GetObject( )
  706. //////////////////////////////////////////////////////////////////////////////
  707. //
  708. // STDMETHODIMP
  709. // CObjectManager::RemoveObject(
  710. // OBJECTCOOKIE cookieIn
  711. // )
  712. //
  713. //////////////////////////////////////////////////////////////////////////////
  714. STDMETHODIMP
  715. CObjectManager::RemoveObject(
  716. OBJECTCOOKIE cookieIn
  717. )
  718. {
  719. TraceFunc( "[IObjectManager]" );
  720. HRESULT hr = E_UNEXPECTED;
  721. CStandardInfo * pcsi;
  722. BOOL fLocked = FALSE;
  723. //
  724. // Check parameters
  725. //
  726. if ( cookieIn == 0 || cookieIn >= m_cCurrentUsed )
  727. goto InvalidArg;
  728. pcsi = m_pCookies[ cookieIn ];
  729. if ( pcsi == NULL )
  730. goto ErrorNotFound;
  731. hr = THR( HrDeleteInstanceAndChildren( cookieIn ) );
  732. if ( FAILED( hr ) )
  733. goto Cleanup;
  734. Cleanup:
  735. HRETURN( hr );
  736. InvalidArg:
  737. hr = THR( E_INVALIDARG );
  738. goto Cleanup;
  739. ErrorNotFound:
  740. hr = THR( HRESULT_FROM_WIN32( ERROR_NOT_FOUND ) );
  741. goto Cleanup;
  742. } // RemoveObject( )
  743. //////////////////////////////////////////////////////////////////////////////
  744. //
  745. // STDMETHODIMP
  746. // CObjectManager::SetObjectStatus(
  747. // OBJECTCOOKIE cookieIn,
  748. // HRESULT hrIn
  749. // )
  750. //
  751. //////////////////////////////////////////////////////////////////////////////
  752. STDMETHODIMP
  753. CObjectManager::SetObjectStatus(
  754. OBJECTCOOKIE cookieIn,
  755. HRESULT hrIn
  756. )
  757. {
  758. TraceFunc( "[IObjectManager]" );
  759. HRESULT hr = S_OK;
  760. CStandardInfo * pcsi;
  761. //
  762. // Check parameters
  763. //
  764. if ( cookieIn == 0 || cookieIn >= m_cCurrentUsed )
  765. goto InvalidArg;
  766. pcsi = m_pCookies[ cookieIn ];
  767. if ( pcsi == NULL )
  768. goto ErrorNotFound;
  769. //
  770. // Update the status.
  771. //
  772. pcsi->m_hrStatus = hrIn;
  773. Cleanup:
  774. HRETURN( hr );
  775. InvalidArg:
  776. hr = THR( E_INVALIDARG );
  777. goto Cleanup;
  778. ErrorNotFound:
  779. hr = THR( HRESULT_FROM_WIN32( ERROR_NOT_FOUND ) );
  780. goto Cleanup;
  781. } // SetObjectStatus( )
  782. //****************************************************************************
  783. //
  784. // Privates
  785. //
  786. //****************************************************************************
  787. //////////////////////////////////////////////////////////////////////////////
  788. //
  789. // HRESULT
  790. // CObjectManager::HrDeleteCookie(
  791. // OBJECTCOOKIE cookieIn
  792. // )
  793. //
  794. //////////////////////////////////////////////////////////////////////////////
  795. HRESULT
  796. CObjectManager::HrDeleteCookie(
  797. OBJECTCOOKIE cookieIn
  798. )
  799. {
  800. TraceFunc1( "cookieIn = %#X", cookieIn );
  801. HRESULT hr = S_OK;
  802. CStandardInfo * pcsi;
  803. Assert( cookieIn != 0 && cookieIn < m_cCurrentUsed );
  804. pcsi = m_pCookies[ cookieIn ];
  805. Assert( pcsi != NULL );
  806. pcsi->Release( );
  807. m_pCookies[ cookieIn ] = NULL;
  808. HRETURN( hr );
  809. } // HrDeleteCookie( )
  810. //////////////////////////////////////////////////////////////////////////////
  811. //
  812. // HRESULT
  813. // CObjectManager::HrSearchForExistingCookie(
  814. // OBJECTCOOKIE cookieIn,
  815. // LPUNKNOWN ppunkOut
  816. // )
  817. //
  818. //////////////////////////////////////////////////////////////////////////////
  819. HRESULT
  820. CObjectManager::HrSearchForExistingCookie(
  821. REFCLSID rclsidTypeIn,
  822. OBJECTCOOKIE cookieParentIn,
  823. LPCWSTR pcszNameIn,
  824. OBJECTCOOKIE * pcookieOut
  825. )
  826. {
  827. TraceFunc( "" );
  828. Assert( pcszNameIn != NULL );
  829. Assert( pcookieOut != NULL );
  830. HRESULT hr = S_FALSE;
  831. ULONG idx;
  832. CStandardInfo * pcsi;
  833. //
  834. // Search the list.
  835. //
  836. for( idx = 1; idx < m_cCurrentUsed; idx ++ )
  837. {
  838. pcsi = m_pCookies[ idx ];
  839. if ( pcsi != NULL )
  840. {
  841. if ( pcsi->m_cookieParent == cookieParentIn // matching parents
  842. && IsEqualIID( pcsi->m_clsidType, rclsidTypeIn ) // matching types
  843. && StrCmpI( pcsi->m_bstrName, pcszNameIn ) == 0 // matching names
  844. )
  845. {
  846. //
  847. // Found a match.
  848. //
  849. *pcookieOut = idx;
  850. hr = S_OK;
  851. break; // exit loop
  852. } // if: match
  853. } // if: cookie exists
  854. } // while: pcsi
  855. HRETURN( hr );
  856. } // HrSearchForExistingCookie( )
  857. //////////////////////////////////////////////////////////////////////////////
  858. //
  859. // HRESULT
  860. // CObjectManager::HrDeleteInstanceAndChildren(
  861. // OBJECTCOOKIE pcsiIn
  862. // )
  863. //
  864. // Notes:
  865. // This should be called while the ListLock is held!
  866. //
  867. //////////////////////////////////////////////////////////////////////////////
  868. HRESULT
  869. CObjectManager::HrDeleteInstanceAndChildren(
  870. OBJECTCOOKIE cookieIn
  871. )
  872. {
  873. TraceFunc1( "cookieIn = %#X", cookieIn );
  874. ULONG idx;
  875. CStandardInfo * pcsi;
  876. HRESULT hr = S_OK;
  877. hr = THR( HrDeleteCookie( cookieIn ) );
  878. if ( FAILED( hr ) )
  879. goto Cleanup;
  880. for ( idx = 1; idx < m_cCurrentUsed; idx ++ )
  881. {
  882. pcsi = m_pCookies[ idx ];
  883. if ( pcsi != NULL
  884. && pcsi->m_cookieParent == cookieIn )
  885. {
  886. hr = THR( HrDeleteInstanceAndChildren( idx ) );
  887. if ( FAILED( hr ) )
  888. goto Cleanup;
  889. } // if:
  890. } // while:
  891. Cleanup:
  892. HRETURN( hr );
  893. } // HrDeleteInstanceAndChildren( )
  894. //////////////////////////////////////////////////////////////////////////////
  895. //
  896. // HRESULT
  897. // CObjectManager::HrCreateNewCookie(
  898. // REFCLSID rclsidTypeIn
  899. // OBJECTCOOKIE cookieParentIn,
  900. // BSTR pcszNameIn,
  901. // OBJECTCOOKIE * pcookieOut
  902. // )
  903. //
  904. //////////////////////////////////////////////////////////////////////////////
  905. HRESULT
  906. CObjectManager::HrCreateNewCookie(
  907. REFCLSID rclsidTypeIn,
  908. OBJECTCOOKIE cookieParentIn,
  909. LPCWSTR pcszNameIn,
  910. OBJECTCOOKIE * pcookieOut
  911. )
  912. {
  913. TraceFunc( "" );
  914. HRESULT hr = E_UNEXPECTED;
  915. CStandardInfo * pcsi = NULL;
  916. Assert( pcookieOut != NULL );
  917. *pcookieOut = 0;
  918. //
  919. // Create some space for it.
  920. //
  921. if ( m_cCurrentUsed == m_cAllocSize )
  922. {
  923. CStandardInfo ** pnew = (CStandardInfo **) TraceAlloc( HEAP_ZERO_MEMORY, sizeof(CStandardInfo *) * ( m_cAllocSize + COOKIE_BUFFER_GROW_SIZE ) );
  924. if ( pnew == NULL )
  925. goto OutOfMemory;
  926. if ( m_pCookies != NULL )
  927. {
  928. CopyMemory( pnew, m_pCookies, sizeof(CStandardInfo *) * m_cCurrentUsed );
  929. TraceFree( m_pCookies );
  930. }
  931. m_pCookies = pnew;
  932. m_cAllocSize += COOKIE_BUFFER_GROW_SIZE;
  933. if ( m_cCurrentUsed == 0 )
  934. {
  935. //
  936. // Always skip zero.
  937. //
  938. m_cCurrentUsed = 1;
  939. }
  940. }
  941. pcsi = new CStandardInfo( );
  942. if ( pcsi == NULL )
  943. goto OutOfMemory;
  944. hr = THR( pcsi->Init( ) );
  945. if ( FAILED( hr ) )
  946. goto Cleanup;
  947. m_pCookies[ m_cCurrentUsed ] = pcsi;
  948. //
  949. // Initialize the rest of the structure.
  950. //
  951. pcsi->m_cookieParent = cookieParentIn;
  952. pcsi->m_hrStatus = E_PENDING;
  953. CopyMemory( &pcsi->m_clsidType, &rclsidTypeIn, sizeof( pcsi->m_clsidType ) );
  954. if ( pcszNameIn != NULL )
  955. {
  956. pcsi->m_bstrName = TraceSysAllocString( pcszNameIn );
  957. if ( pcsi->m_bstrName == NULL )
  958. {
  959. m_cCurrentUsed --;
  960. goto OutOfMemory;
  961. } // if: out of memory
  962. }
  963. Assert( pcsi->m_pci == NULL );
  964. Assert( pcsi->m_pExtObjList == NULL );
  965. //
  966. // Keep it around and return SUCCESS!
  967. //
  968. pcsi = NULL;
  969. *pcookieOut = m_cCurrentUsed;
  970. m_cCurrentUsed ++;
  971. hr = S_OK;
  972. Cleanup:
  973. if ( pcsi != NULL )
  974. {
  975. pcsi->Release( );
  976. }
  977. HRETURN( hr );
  978. OutOfMemory:
  979. hr = E_OUTOFMEMORY;
  980. goto Cleanup;
  981. } // HrCreateNewCookie( )