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.

997 lines
24 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File:
  4. // oaholder.cpp
  5. //
  6. // Contents:
  7. // COAHolder, a concrete implementation of IOleAdviseHolder,
  8. // a helper class
  9. //
  10. // Classes:
  11. // COAHolder
  12. //
  13. // Functions:
  14. // CreateOleAdviseHolder
  15. //
  16. // History:
  17. // 31-Jan-95 t-ScottH added _DEBUG only Dump method to the
  18. // COAHolder class and a DumpCOAHolder
  19. // API
  20. // 03/10/94 - RickSa - added call logging and fixed bugs with
  21. // inserting advises
  22. // 01/24/94 - AlexGo - first pass at converting to Cairo style
  23. // memory allocation
  24. // 01/11/93 - AlexGo - added VDATEHEAP macros to all functions
  25. // and methods
  26. // 11/22/93 - ChrisWe - replace overloaded ==, != with
  27. // IsEqualIID and IsEqualCLSID
  28. // 10/28/93 - ChrisWe - file cleanup and inspection for Cairo
  29. //
  30. //-----------------------------------------------------------------------------
  31. #include <le2int.h>
  32. #include <oaholder.h>
  33. #include <limits.h>
  34. #ifdef _DEBUG
  35. #include <dbgdump.h>
  36. #endif // _DEBUG
  37. #pragma SEG(oaholder)
  38. NAME_SEG(OaHolder)
  39. ASSERTDATA
  40. //+----------------------------------------------------------------------------
  41. //
  42. // Function:
  43. // CreateDataAdviseHolder, public API
  44. //
  45. // Synopsis:
  46. // Creates an instance of the COAHolder
  47. //
  48. // Arguments:
  49. // [ppOAHolder] -- place to return pointer to newly allocated
  50. // advise holder
  51. //
  52. // Returns:
  53. // E_INVALIDARG, if ppOAHolder is NULL
  54. // E_OUTOFMEMORY
  55. //
  56. // Notes:
  57. //
  58. // History:
  59. // 10/28/93 - ChrisWe - file cleanup and inspection
  60. //
  61. //-----------------------------------------------------------------------------
  62. #pragma SEG(CreateOleAdviseHolder)
  63. STDAPI CreateOleAdviseHolder(IOleAdviseHolder FAR* FAR* ppOAHolder)
  64. {
  65. OLETRACEIN((API_CreateOleAdviseHolder, PARAMFMT("ppOAHolder= %p"), ppOAHolder));
  66. VDATEHEAP();
  67. HRESULT hr;
  68. VDATEPTROUT_LABEL(ppOAHolder, IOleAdviseHolder FAR* FAR*, errRtn, hr);
  69. LEDebugOut((DEB_ITRACE, "%p _IN CreateOleAdviseHolder ( %p )"
  70. "\n", NULL, ppOAHolder));
  71. *ppOAHolder = new FAR COAHolder(); // task memory; hard coded below
  72. hr = *ppOAHolder
  73. ? NOERROR : ReportResult(0, E_OUTOFMEMORY, 0, 0);
  74. LEDebugOut((DEB_ITRACE, "%p OUT CreateOleAdviseHolder ( %lx )\n",
  75. "[ %p ]\n", NULL, hr, *ppOAHolder));
  76. CALLHOOKOBJECTCREATE(hr, CLSID_NULL, IID_IOleAdviseHolder,
  77. (IUnknown **)ppOAHolder);
  78. errRtn:
  79. OLETRACEOUT((API_CreateOleAdviseHolder, hr));
  80. return hr;
  81. }
  82. //+----------------------------------------------------------------------------
  83. //
  84. // Member:
  85. // COAHolder::COAHolder, public
  86. //
  87. // Synopsis:
  88. // Initializes COAHolder
  89. //
  90. // Effects:
  91. // Sets reference count to 1
  92. //
  93. // Arguments:
  94. // none
  95. //
  96. // Notes:
  97. //
  98. // History:
  99. // 10/28/93 - ChrisWe - file cleanup and inspection
  100. //
  101. //-----------------------------------------------------------------------------
  102. #pragma SEG(COAHolder_ctor)
  103. COAHolder::COAHolder() : CSafeRefCount(NULL)
  104. {
  105. VDATEHEAP();
  106. // set reference count to 1
  107. SafeAddRef();
  108. // no sink pointers yet
  109. m_iSize = 0;
  110. m_ppIAS = NULL;
  111. GET_A5();
  112. }
  113. //+----------------------------------------------------------------------------
  114. //
  115. // Member:
  116. // COAHolder::~COAHolder, private
  117. //
  118. // Synopsis:
  119. // destructor, frees managed advise sinks
  120. //
  121. // Arguments:
  122. // none
  123. //
  124. // Requires:
  125. //
  126. // Notes:
  127. //
  128. // History:
  129. // 10/28/93 - ChrisWe - file inspection and cleanup
  130. //
  131. //-----------------------------------------------------------------------------
  132. #pragma SEG(COAHolder_dtor)
  133. COAHolder::~COAHolder()
  134. {
  135. VDATEHEAP();
  136. int iAdv;
  137. IAdviseSink FAR *FAR *ppIAS;
  138. M_PROLOG(this);
  139. // free the array, if there is one
  140. if (m_ppIAS)
  141. {
  142. // walk the array of advise sinks, freeing things
  143. for (ppIAS = m_ppIAS, iAdv = 0; iAdv < m_iSize; ++ppIAS, ++iAdv)
  144. {
  145. SafeReleaseAndNULL((IUnknown **)ppIAS);
  146. }
  147. // free the array
  148. PubMemFree(m_ppIAS);
  149. }
  150. }
  151. //+----------------------------------------------------------------------------
  152. //
  153. // Member:
  154. // COAHolder::QueryInterface, public
  155. //
  156. // Synopsis:
  157. // implements IUnknown::QueryInterface
  158. //
  159. // Arguments:
  160. // [iid] -- the interface pointer desired
  161. // [ppv] -- pointer to where to return the requested interface
  162. // pointer
  163. //
  164. // Returns:
  165. // E_NOINTERFACE, if requested interface not available
  166. // S_OK
  167. //
  168. // Notes:
  169. //
  170. // History:
  171. // 10/28/93 - ChrisWe - file inspection and cleanup
  172. //
  173. //-----------------------------------------------------------------------------
  174. #pragma SEG(COAHolder_QueryInterface)
  175. STDMETHODIMP COAHolder::QueryInterface(REFIID iid, LPVOID FAR* ppv)
  176. {
  177. VDATEHEAP();
  178. M_PROLOG(this);
  179. VDATEPTROUT(ppv, LPVOID FAR *);
  180. LEDebugOut((DEB_ITRACE,
  181. "%p _IN COAHolder::QueryInterface ( %p , %p )"
  182. "\n", this, iid, ppv));
  183. HRESULT hr = ReportResult(0, E_NOINTERFACE, 0, 0);
  184. if (IsEqualIID(iid, IID_IUnknown) ||
  185. IsEqualIID(iid, IID_IOleAdviseHolder))
  186. {
  187. *ppv = (IOleAdviseHolder FAR *)this;
  188. AddRef();
  189. hr = NOERROR;
  190. }
  191. else
  192. {
  193. *ppv = NULL;
  194. }
  195. LEDebugOut((DEB_ITRACE, "%p OUT COAHolder::QueryInterface ( %lx )"
  196. " [ %p ]\n", this, hr, *ppv));
  197. return hr;
  198. }
  199. //+----------------------------------------------------------------------------
  200. //
  201. // Member:
  202. // COAHolder::AddRef, public
  203. //
  204. // Synopsis:
  205. // implements IUnknown::AddRef
  206. //
  207. // Arguments:
  208. // none
  209. //
  210. // Notes:
  211. //
  212. // History:
  213. // 10/28/93 - ChrisWe - file inspection and cleanup
  214. //
  215. //-----------------------------------------------------------------------------
  216. #pragma SEG(COAHolder_AddRef)
  217. STDMETHODIMP_(ULONG) COAHolder::AddRef()
  218. {
  219. ULONG cRefs;
  220. VDATEHEAP();
  221. M_PROLOG(this);
  222. LEDebugOut((DEB_ITRACE, "%p _IN COAHolder::AddRef ( )\n", this));
  223. cRefs = SafeAddRef();
  224. LEDebugOut((DEB_ITRACE, "%p OUT COAHolder::AddRef ( %lu )\n", this,
  225. cRefs));
  226. return cRefs;
  227. }
  228. //+----------------------------------------------------------------------------
  229. //
  230. // Member:
  231. // COAHolder::Release, public
  232. //
  233. // Synopsis:
  234. // implements IUnknown::Release
  235. //
  236. // Arguments:
  237. // none
  238. //
  239. // Notes:
  240. //
  241. // History:
  242. // 10/28/93 - ChrisWe - file inspection and cleanup
  243. //
  244. //-----------------------------------------------------------------------------
  245. #pragma SEG(COAHolder_Release)
  246. STDMETHODIMP_(ULONG) COAHolder::Release()
  247. {
  248. VDATEHEAP();
  249. M_PROLOG(this);
  250. ULONG cRefs;
  251. LEDebugOut((DEB_ITRACE, "%p _IN COAHolder::Release ( )\n", this ));
  252. cRefs = SafeRelease();
  253. LEDebugOut((DEB_ITRACE, "%p OUT COAHolder::Release ( %lu )\n", this,
  254. cRefs));
  255. return cRefs;
  256. }
  257. //+----------------------------------------------------------------------------
  258. //
  259. // Member:
  260. // COAHolder::Advise, public
  261. //
  262. // Synopsis:
  263. // implements IOleAdviseHolder::Advise
  264. //
  265. // Effects:
  266. // Adds the newly specified advise sink the the list of
  267. // advisees that will be notified when a change is indicated
  268. // via other IOleAdviseHolder methods on this object
  269. //
  270. // Arguments:
  271. // [pAdvSink] -- the new advise sink to add the the list
  272. // [pdwConnection] -- pointer to a DWORD where an identifier will
  273. // be returned that can be used to identify this sink
  274. // later
  275. //
  276. // Returns:
  277. // E_OUTOFMEMORY, S_OK
  278. //
  279. // Notes:
  280. //
  281. // History:
  282. // 10/28/93 - ChrisWe - file inspection and cleanup
  283. // 03/15/94 - AlexT Zero out new space after a realloc
  284. // 08/02/94 - AlexGo - stabilized
  285. //
  286. //-----------------------------------------------------------------------------
  287. #pragma SEG(COAHolder_Advise)
  288. STDMETHODIMP COAHolder::Advise(IAdviseSink FAR* pAdvSink,
  289. DWORD FAR* pdwConnection)
  290. {
  291. VDATEHEAP();
  292. int iAdv; // records the first free entry found, or (-1)
  293. int iAdvScan; // counts across array entries
  294. IAdviseSink FAR *FAR *ppIAS; // points at the array entry being examined
  295. IAdviseSink FAR *pIAS; // the actual entry at *ppIAS
  296. M_PROLOG(this);
  297. VDATEIFACE(pAdvSink);
  298. HRESULT hr = NOERROR;
  299. LEDebugOut((DEB_ITRACE, "%p _IN COAHolder::Advise ( %p , %p )"
  300. "\n", this, pAdvSink, pdwConnection));
  301. // Validate where to return the connection.
  302. if (pdwConnection)
  303. {
  304. VDATEPTRIN(pdwConnection, DWORD);
  305. // Default to error case
  306. *pdwConnection = 0;
  307. }
  308. // check our zombie state and stabilize. If we are in a zombie
  309. // state, we do not want to be adding new advise sinks.
  310. CStabilize stabilize((CSafeRefCount *)this);
  311. if( IsZombie() )
  312. {
  313. hr = ResultFromScode(CO_E_RELEASED);
  314. goto errRtn;
  315. }
  316. // find an empty slot and clean up disconnected handlers
  317. for (iAdv = (-1), ppIAS = m_ppIAS, iAdvScan = 0;
  318. iAdvScan < m_iSize; ++ppIAS, ++iAdvScan)
  319. {
  320. if ((pIAS = *ppIAS) == NULL)
  321. {
  322. // NULL entries are handled below, to catch
  323. // any of the below cases creating new NULL values
  324. ;
  325. }
  326. else if (!IsValidInterface(pIAS))
  327. {
  328. // not valid; don't try to release
  329. *ppIAS = NULL;
  330. }
  331. else if (!CoIsHandlerConnected(pIAS))
  332. {
  333. // advise sink not connected to server anymore; release
  334. // REVIEW, why do we have to constantly poll these
  335. // to see if they are ok?
  336. pIAS->Release();
  337. *ppIAS = NULL;
  338. }
  339. // if first NULL, save rather than extend array
  340. if ((*ppIAS == NULL) && (iAdv == (-1)))
  341. iAdv = iAdvScan;
  342. }
  343. // if we didn't find an empty slot, we have to add space
  344. if (iAdv == (-1))
  345. {
  346. ppIAS = (IAdviseSink FAR * FAR *)PubMemRealloc(m_ppIAS,
  347. sizeof(IAdviseSink FAR *)*(m_iSize + COAHOLDER_GROWBY));
  348. if (ppIAS != NULL)
  349. {
  350. // zero out new space
  351. _xmemset((void FAR *) (ppIAS + m_iSize), 0,
  352. sizeof(IAdviseSink *) * COAHOLDER_GROWBY);
  353. // this is the index of the new element to use
  354. iAdv = m_iSize;
  355. // replace the old array
  356. m_ppIAS = ppIAS;
  357. m_iSize += COAHOLDER_GROWBY;
  358. }
  359. else
  360. {
  361. // quit if there was an error
  362. hr = ReportResult(0, E_OUTOFMEMORY, 0, 0);
  363. }
  364. }
  365. if (SUCCEEDED(hr))
  366. {
  367. // if we get here, iAdv is the element to use; if the addition
  368. // was not possible, function would have returned before now
  369. pAdvSink->AddRef();
  370. m_ppIAS[iAdv] = pAdvSink;
  371. // if user wants cookie back, return it
  372. if (pdwConnection)
  373. {
  374. // NOTE: this +1 is balanced by -1 in Unadvise()
  375. *pdwConnection = iAdv + 1;
  376. }
  377. }
  378. errRtn:
  379. LEDebugOut((DEB_ITRACE, "%p OUT COAHolder::Advise ( %lx )"
  380. " [ %p ]\n", this, hr,
  381. (pdwConnection)? *pdwConnection : 0));
  382. return hr;
  383. }
  384. //+----------------------------------------------------------------------------
  385. //
  386. // Member:
  387. // COAHolder::Unadvise, public
  388. //
  389. // Synopsis:
  390. // implementat IOleAdviseHolder::Unadvise
  391. //
  392. // Effects:
  393. // removes the specified advise sink from the list of sinks that
  394. // are notified when other IOleAdviseHolder methods are used on
  395. // this
  396. //
  397. // Arguments:
  398. // [dwConnection] -- The token that identifies the connection;
  399. // this would have been obtained previously from a
  400. // call to Advise()
  401. //
  402. // Returns:
  403. // OLE_E_NOCONNECTION, if the connection token is invalid
  404. // S_OK
  405. //
  406. // Notes: We do not have to stabilize this call since the only
  407. // outgoing call is the Release at the end
  408. //
  409. // History:
  410. // 10/28/93 - ChrisWe - file inspection and cleanup
  411. //
  412. //-----------------------------------------------------------------------------
  413. #pragma SEG(COAHolder_Unadvise)
  414. STDMETHODIMP COAHolder::Unadvise(DWORD dwConnection)
  415. {
  416. VDATEHEAP();
  417. M_PROLOG(this);
  418. HRESULT hr = NOERROR;
  419. LEDebugOut((DEB_ITRACE, "%p _IN COAHolder::Unadvise ( %lu )"
  420. "\n", this, dwConnection));
  421. IAdviseSink FAR* pAdvSink; // the requested advise sink, if there is one
  422. int iAdv = (int)dwConnection - 1; // adjust connection index
  423. // check that the connection token is valid, and if so, check that
  424. // there is a connection for it
  425. if (((LONG)dwConnection <= 0)
  426. || (iAdv >= m_iSize)
  427. || ((LONG)dwConnection > INT_MAX)
  428. || ((pAdvSink = m_ppIAS[iAdv]) == NULL)
  429. || !IsValidInterface(pAdvSink))
  430. {
  431. hr = ReportResult(0, OLE_E_NOCONNECTION, 0, 0);
  432. }
  433. else
  434. {
  435. // remove the advise sink from the array
  436. m_ppIAS[iAdv] = NULL;
  437. // release the advise sink; NB, due to circular references, this
  438. // may release this advise holder--[this] may not be valid on
  439. // return!
  440. pAdvSink->Release();
  441. }
  442. // NB!! If any outgoing calls are added, this function will have
  443. // to be stabilized
  444. LEDebugOut((DEB_ITRACE, "%p OUT COAHolder::Unadvise ( %lx )"
  445. " \n", this, hr));
  446. return hr;
  447. }
  448. //+----------------------------------------------------------------------------
  449. //
  450. // Member:
  451. // COAHolder::EnumAdvise, public
  452. //
  453. // Synopsis:
  454. // implements IOleAdviseHolder::EnumAdvise()
  455. //
  456. // Effects:
  457. // returns an enumerator
  458. //
  459. // Arguments:
  460. // [ppenumAdvise] -- pointer to where to return a pointer to
  461. // an enumerator
  462. //
  463. // Returns:
  464. // E_NOTIMPL
  465. //
  466. // Notes:
  467. // currently not implemented.
  468. //
  469. // History:
  470. // 10/28/93 - ChrisWe - file inspection and cleanup
  471. //
  472. //-----------------------------------------------------------------------------
  473. #pragma SEG(COAHolder_EnumAdvise)
  474. STDMETHODIMP COAHolder::EnumAdvise(IEnumSTATDATA FAR* FAR* ppenumAdvise)
  475. {
  476. VDATEHEAP();
  477. M_PROLOG(this);
  478. // This is currently not implemented
  479. HRESULT hr = ReportResult(0, E_NOTIMPL, 0, 0);
  480. VDATEPTROUT(ppenumAdvise, IEnumSTATDATA FAR*);
  481. LEDebugOut((DEB_ITRACE, "%p _IN COAHolder::EnumAdvise ( )"
  482. "\n", this));
  483. *ppenumAdvise = NULL;
  484. LEDebugOut((DEB_ITRACE, "%p OUT COAHolder::EnumAdvise ( %lx )"
  485. "[ %p ]\n", this, hr, *ppenumAdvise));
  486. return hr;
  487. }
  488. //+----------------------------------------------------------------------------
  489. //
  490. // Member:
  491. // COAHolder::SendOnRename(), public
  492. //
  493. // Synopsis:
  494. // Multicast the OnRename OLE compound document notification,
  495. // to all interested parties
  496. //
  497. // Arguments:
  498. // [pmk] -- the new name of the object
  499. //
  500. // Returns:
  501. // S_OK
  502. //
  503. // Notes:
  504. // This may release the advise holder, since some objects may
  505. // Unadvise() themselves at the time they receive this
  506. // notification. To prevent the multicasting code from crashing,
  507. // the multicast loop is bracketed with AddRef()/Release(). Note
  508. // that the bracketing Release() may release the advise holder,
  509. // at which point [this] may no longer be valid.
  510. //
  511. // In a similar vein, other parties may add new Advise sinks
  512. // during these notifications. To avoid getting caught in
  513. // an infinite loop, we copy the number of advise sinks at the
  514. // beginning of the function, and do not refer to the current
  515. // number. If some parties are removed, and re-added, they may
  516. // be notified more than once, if they happen to be moved to
  517. // a later spot in the array of advise sinks.
  518. // REVIEW, copied this comment from previous stuff, and it
  519. // sounds BOGUS. Since new entries are always put in the first
  520. // empty slot, the current number always has to settle down,
  521. // and won't grow without bound, unless some bogus app is
  522. // continually registering itself when it gets a notification
  523. //
  524. // History:
  525. // 10/28/93 - ChrisWe - file inspection and cleanup
  526. //
  527. //-----------------------------------------------------------------------------
  528. #pragma SEG(COAHolder_SendOnRename)
  529. STDMETHODIMP COAHolder::SendOnRename(IMoniker FAR* pmk)
  530. {
  531. VDATEHEAP();
  532. M_PROLOG(this);
  533. VDATEIFACE(pmk);
  534. HRESULT hr = NOERROR;
  535. int iAdvLim = m_iSize; // copy the current number of sink entries
  536. int iAdv;
  537. IAdviseSink FAR *FAR *ppIAS;
  538. LEDebugOut((DEB_ITRACE, "%p _IN COAHolder::SendOnRename ( %p )"
  539. "\n", this, pmk));
  540. // protect the COAHolder
  541. CStabilize stabilize((CSafeRefCount *)this);
  542. for (ppIAS = m_ppIAS, iAdv = 0; iAdv < iAdvLim; ++ppIAS, ++iAdv)
  543. {
  544. if (*ppIAS != NULL)
  545. (*ppIAS)->OnRename(pmk);
  546. }
  547. LEDebugOut((DEB_ITRACE, "%p OUT COAHolder::SendOnRename ( %lx )"
  548. " \n", this, hr));
  549. return hr;
  550. }
  551. //+----------------------------------------------------------------------------
  552. //
  553. // Member:
  554. // COAHolder::SendOnSave(), public
  555. //
  556. // Synopsis:
  557. // Multicast the OnSave OLE compound document notification,
  558. // to all interested parties
  559. //
  560. // Arguments:
  561. // none
  562. //
  563. // Returns:
  564. // S_OK
  565. //
  566. // Notes:
  567. // See notes for COAHolder::SendOnRename().
  568. //
  569. // History:
  570. // 10/28/93 - ChrisWe - file inspection and cleanup
  571. //
  572. //-----------------------------------------------------------------------------
  573. #pragma SEG(COAHolder_SendOnSave)
  574. STDMETHODIMP COAHolder::SendOnSave(void)
  575. {
  576. VDATEHEAP();
  577. M_PROLOG(this);
  578. HRESULT hr = NOERROR;
  579. LEDebugOut((DEB_ITRACE, "%p _IN COAHolder::SendOnSave ( )"
  580. "\n", this ));
  581. int iAdvLim = m_iSize; // copy the current number of sink entries
  582. int iAdv;
  583. IAdviseSink FAR *FAR *ppIAS;
  584. // protect the COAHolder
  585. CStabilize stabilize((CSafeRefCount *)this);
  586. for (ppIAS = m_ppIAS, iAdv = 0; iAdv < iAdvLim; ++ppIAS, ++iAdv)
  587. {
  588. if (*ppIAS != NULL)
  589. (*ppIAS)->OnSave();
  590. }
  591. LEDebugOut((DEB_ITRACE, "%p OUT COAHolder::SendOnSave ( %lx )"
  592. " \n", this, hr));
  593. return hr;
  594. }
  595. //+----------------------------------------------------------------------------
  596. //
  597. // Member:
  598. // COAHolder::SendOnClose(), public
  599. //
  600. // Synopsis:
  601. // Multicast the OnClose OLE compound document notification,
  602. // to all interested parties
  603. //
  604. // Arguments:
  605. // none
  606. //
  607. // Returns:
  608. // S_OK
  609. //
  610. // Notes:
  611. // See notes for COAHolder::SendOnRename().
  612. //
  613. // History:
  614. // 10/28/93 - ChrisWe - file inspection and cleanup
  615. //
  616. //-----------------------------------------------------------------------------
  617. #pragma SEG(COAHolder_SendOnClose)
  618. STDMETHODIMP COAHolder::SendOnClose(void)
  619. {
  620. VDATEHEAP();
  621. M_PROLOG(this);
  622. HRESULT hr = NOERROR;
  623. LEDebugOut((DEB_ITRACE, "%p _IN COAHolder::SendOnClose ( )"
  624. "\n", this));
  625. int iAdvLim = m_iSize; // copy the current number of sink entries
  626. int iAdv;
  627. IAdviseSink FAR *FAR *ppIAS;
  628. // protect the COAHolder
  629. CStabilize stabilize((CSafeRefCount *)this);
  630. for (ppIAS = m_ppIAS, iAdv = 0; iAdv < iAdvLim; ++ppIAS, ++iAdv)
  631. {
  632. if (*ppIAS != NULL)
  633. (*ppIAS)->OnClose();
  634. }
  635. LEDebugOut((DEB_ITRACE, "%p OUT COAHolder::SendOnClose ( %lx )"
  636. " \n", this, hr));
  637. return hr;
  638. }
  639. //+----------------------------------------------------------------------------
  640. //
  641. // Member:
  642. // COAHolder::SendOnLinkSrcChange, public
  643. //
  644. // Synopsis:
  645. // Multicasts IAdviseSink2::OnLinkSrcChange notification to any
  646. // advise sinks managed by the COAHolder that provide the
  647. // IAdviseSink2 interface
  648. //
  649. // Arguments:
  650. // [pmk] -- the new moniker to the link source
  651. //
  652. // Returns:
  653. // S_OK
  654. //
  655. // Notes:
  656. //
  657. // History:
  658. // 12/31/93 - ChrisWe - fixed assert
  659. // 11/01/93 - ChrisWe - made a member of COAHolder
  660. // 10/28/93 - ChrisWe - file inspection and cleanup
  661. //
  662. //-----------------------------------------------------------------------------
  663. #pragma SEG(COAHolder_SendOnLinkSrcChange)
  664. HRESULT COAHolder::SendOnLinkSrcChange(IMoniker FAR* pmk)
  665. {
  666. VDATEHEAP();
  667. M_PROLOG(this);
  668. VDATEIFACE(pmk);
  669. HRESULT hr = NOERROR;
  670. LEDebugOut((DEB_ITRACE, "%p _IN COAHolder::SendOnLinkSrcChange ( %p )"
  671. "\n", this, pmk));
  672. int iAdvLim = m_iSize; // records the number of entries at start
  673. int iAdv; // counts entries
  674. IAdviseSink FAR *FAR *ppIAS; // walks over the array of advise sinks
  675. // protect this from being released through circular references
  676. CStabilize stabilize((CSafeRefCount *)this);
  677. // multicast notification
  678. for (ppIAS = m_ppIAS, iAdv = 0; iAdv < iAdvLim; ++ppIAS, ++iAdv)
  679. {
  680. IAdviseSink FAR* pAdvSink;
  681. IAdviseSink2 FAR* pAdvSink2;
  682. // REVIEW, this seems to require that the number of
  683. // advisees can only stay the same, or increase. Why should
  684. // we care?
  685. Assert(iAdvLim <= m_iSize);
  686. // get pointer to current advise sink
  687. pAdvSink = *ppIAS;
  688. // if we have an advise sink, and it accepts IAdviseSink2
  689. // notifications, send one
  690. if ((pAdvSink != NULL) &&
  691. pAdvSink->QueryInterface(IID_IAdviseSink2,
  692. (LPVOID FAR*)&pAdvSink2) == NOERROR)
  693. {
  694. pAdvSink2->OnLinkSrcChange(pmk);
  695. pAdvSink2->Release();
  696. }
  697. }
  698. LEDebugOut((DEB_ITRACE, "%p OUT COAHolder::SendOnLinkSrcChange ( %lx )"
  699. " \n", this, hr));
  700. return hr;
  701. }
  702. //+-------------------------------------------------------------------------
  703. //
  704. // Member: COAHolder::Dump, public (_DEBUG only)
  705. //
  706. // Synopsis: return a string containing the contents of the data members
  707. //
  708. // Effects:
  709. //
  710. // Arguments: [ppszDump] - an out pointer to a null terminated character array
  711. // [ulFlag] - flag determining prefix of all newlines of the
  712. // out character array (default is 0 - no prefix)
  713. // [nIndentLevel] - will add a indent prefix after the other prefix
  714. // for ALL newlines (including those with no prefix)
  715. //
  716. // Requires:
  717. //
  718. // Returns: HRESULT
  719. //
  720. // Signals:
  721. //
  722. // Modifies: [ppszDump] - argument
  723. //
  724. // Derivation:
  725. //
  726. // Algorithm: use dbgstream to create a string containing information on the
  727. // content of data structures
  728. //
  729. // History: dd-mmm-yy Author Comment
  730. // 31-Jan-95 t-ScottH author
  731. //
  732. // Notes:
  733. //
  734. //--------------------------------------------------------------------------
  735. #ifdef _DEBUG
  736. HRESULT COAHolder::Dump(char **ppszDump, ULONG ulFlag, int nIndentLevel)
  737. {
  738. int i;
  739. char *pszPrefix;
  740. char *pszCSafeRefCount;
  741. dbgstream dstrPrefix;
  742. dbgstream dstrDump;
  743. // determine prefix of newlines
  744. if ( ulFlag & DEB_VERBOSE )
  745. {
  746. dstrPrefix << this << " _VB ";
  747. }
  748. // determine indentation prefix for all newlines
  749. for (i = 0; i < nIndentLevel; i++)
  750. {
  751. dstrPrefix << DUMPTAB;
  752. }
  753. pszPrefix = dstrPrefix.str();
  754. // put data members in stream
  755. dstrDump << pszPrefix << "No. of Advise Sinks = " << m_iSize << endl;
  756. for (i = 0; i < m_iSize; i++)
  757. {
  758. dstrDump << pszPrefix << "pIAdviseSink [" << i << "] = " << m_ppIAS[i] << endl;
  759. }
  760. // cleanup and provide pointer to character array
  761. *ppszDump = dstrDump.str();
  762. if (*ppszDump == NULL)
  763. {
  764. *ppszDump = UtDupStringA(szDumpErrorMessage);
  765. }
  766. CoTaskMemFree(pszPrefix);
  767. return NOERROR;
  768. }
  769. #endif // _DEBUG
  770. //+-------------------------------------------------------------------------
  771. //
  772. // Function: DumpCOAHolder, public (_DEBUG only)
  773. //
  774. // Synopsis: calls the COAHolder::Dump method, takes care of errors and
  775. // returns the zero terminated string
  776. //
  777. // Effects:
  778. //
  779. // Arguments: [pESD] - pointer to COAHolder
  780. // [ulFlag] - flag determining prefix of all newlines of the
  781. // out character array (default is 0 - no prefix)
  782. // [nIndentLevel] - will add a indent prefix after the other prefix
  783. // for ALL newlines (including those with no prefix)
  784. //
  785. // Requires:
  786. //
  787. // Returns: character array of structure dump or error (null terminated)
  788. //
  789. // Signals:
  790. //
  791. // Modifies:
  792. //
  793. // Algorithm:
  794. //
  795. // History: dd-mmm-yy Author Comment
  796. // 20-Jan-95 t-ScottH author
  797. //
  798. // Notes:
  799. //
  800. //--------------------------------------------------------------------------
  801. #ifdef _DEBUG
  802. char *DumpCOAHolder(COAHolder *pOAH, ULONG ulFlag, int nIndentLevel)
  803. {
  804. HRESULT hresult;
  805. char *pszDump;
  806. if (pOAH == NULL)
  807. {
  808. return UtDupStringA(szDumpBadPtr);
  809. }
  810. hresult = pOAH->Dump(&pszDump, ulFlag, nIndentLevel);
  811. if (hresult != NOERROR)
  812. {
  813. CoTaskMemFree(pszDump);
  814. return DumpHRESULT(hresult);
  815. }
  816. return pszDump;
  817. }
  818. #endif // _DEBUG