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.

866 lines
22 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995
  5. //
  6. // File: object.cxx
  7. //
  8. // Contents: Implementation of the CLocalMTProxy class and
  9. // associated objects.
  10. //
  11. //----------------------------------------------------------------------------
  12. #include "headers.hxx"
  13. #include "mtscript.h" // MIDL generated file
  14. #include "localobj.h"
  15. long g_lObjectCount = 0;
  16. // ***********************************************************************
  17. //
  18. // CLocalProxyCP
  19. //
  20. // ConnectionPoint for CLocalMTProxy
  21. //
  22. // ***********************************************************************
  23. CLocalProxyCP::CLocalProxyCP(CLocalMTProxy *pMach)
  24. {
  25. _ulRefs = 1;
  26. _pMTProxy = pMach;
  27. _pMTProxy->AddRef();
  28. }
  29. CLocalProxyCP::~CLocalProxyCP()
  30. {
  31. _pMTProxy->Release();
  32. }
  33. HRESULT
  34. CLocalProxyCP::QueryInterface(REFIID iid, void **ppv)
  35. {
  36. if (iid == IID_IUnknown || iid == IID_IConnectionPoint)
  37. {
  38. *ppv = (IConnectionPoint *)this;
  39. }
  40. else
  41. {
  42. *ppv = NULL;
  43. return E_NOINTERFACE;
  44. }
  45. ((IUnknown *)*ppv)->AddRef();
  46. return S_OK;
  47. }
  48. HRESULT
  49. CLocalProxyCP::GetConnectionInterface(IID * pIID)
  50. {
  51. *pIID = DIID_DRemoteMTScriptEvents;
  52. return S_OK;
  53. }
  54. HRESULT
  55. CLocalProxyCP::GetConnectionPointContainer(IConnectionPointContainer ** ppCPC)
  56. {
  57. *ppCPC = _pMTProxy;
  58. (*ppCPC)->AddRef();
  59. return S_OK;
  60. }
  61. //+---------------------------------------------------------------------------
  62. //
  63. // Member: CLocalProxyCP::Advise, public
  64. //
  65. // Synopsis: Remembers interface pointers that we want to fire events
  66. // through.
  67. //
  68. // Arguments: [pUnkSink] -- Pointer to remember
  69. // [pdwCookie] -- Place to put cookie for Unadvise
  70. //
  71. // Returns: HRESULT
  72. //
  73. //----------------------------------------------------------------------------
  74. HRESULT
  75. CLocalProxyCP::Advise(IUnknown *pUnkSink, DWORD *pdwCookie)
  76. {
  77. IDispatch *pDisp;
  78. HRESULT hr;
  79. TraceTag((tagError, "CLocalProxyCP::Advise: Advising %p", pUnkSink));
  80. hr = pUnkSink->QueryInterface(IID_IDispatch, (LPVOID*)&pDisp);
  81. if (hr)
  82. {
  83. return hr;
  84. }
  85. // We can only keep one sink at a time.
  86. ReleaseInterface(_pMTProxy->_pDispSink);
  87. _pMTProxy->_pDispSink = pDisp;
  88. *pdwCookie = (DWORD)pDisp;
  89. return S_OK;
  90. }
  91. //+---------------------------------------------------------------------------
  92. //
  93. // Member: CLocalProxyCP::Unadvise, public
  94. //
  95. // Synopsis: Forgets a pointer we remembered during Advise.
  96. //
  97. // Arguments: [dwCookie] -- Cookie returned from Advise
  98. //
  99. // Returns: HRESULT
  100. //
  101. //----------------------------------------------------------------------------
  102. HRESULT
  103. CLocalProxyCP::Unadvise(DWORD dwCookie)
  104. {
  105. TraceTag((tagError, "CLocalProxyCP::Unadvise: Unadvising %p", dwCookie));
  106. if (dwCookie == (DWORD)_pMTProxy->_pDispSink)
  107. {
  108. ClearInterface(&_pMTProxy->_pDispSink);
  109. }
  110. else
  111. return E_INVALIDARG;
  112. return S_OK;
  113. }
  114. HRESULT
  115. CLocalProxyCP::EnumConnections(LPENUMCONNECTIONS * ppEnum)
  116. {
  117. *ppEnum = NULL;
  118. RRETURN(E_NOTIMPL);
  119. }
  120. // ***********************************************************************
  121. //
  122. // CLocalMTProxy
  123. //
  124. // ***********************************************************************
  125. CLocalMTProxy::CLocalMTProxy()
  126. {
  127. _ulRefs = 1;
  128. _ulAllRefs = 1;
  129. InterlockedIncrement(&g_lObjectCount);
  130. Assert(_pTypeInfoInterface == NULL);
  131. Assert(_pTypeLibDLL == NULL);
  132. }
  133. CLocalMTProxy::~CLocalMTProxy()
  134. {
  135. ReleaseInterface(_pTypeInfoInterface);
  136. ReleaseInterface(_pTypeInfoCM);
  137. ReleaseInterface(_pTypeLibDLL);
  138. InterlockedDecrement(&g_lObjectCount);
  139. }
  140. //+---------------------------------------------------------------------------
  141. //
  142. // Member: CLocalMTProxy::Passivate, public
  143. //
  144. // Synopsis: Called when the refcount for CLocalMTProxy goes to zero. This
  145. // will cause us to let go of all the objects we hold onto, which
  146. // in turn should cause everyone else to let go of our subobjects.
  147. // When that happens we can finally delete ourselves.
  148. //
  149. //----------------------------------------------------------------------------
  150. void
  151. CLocalMTProxy::Passivate()
  152. {
  153. Disconnect();
  154. ClearInterface(&_pDispSink);
  155. }
  156. //+---------------------------------------------------------------------------
  157. //
  158. // Member: CLocalMTProxy::QueryInterface, public
  159. //
  160. // Synopsis: Standard IUnknown::QueryInterface
  161. //
  162. //----------------------------------------------------------------------------
  163. HRESULT
  164. CLocalMTProxy::QueryInterface(REFIID iid, void **ppvObj)
  165. {
  166. if (iid == IID_IRemoteMTScriptProxy || iid == IID_IUnknown || iid == IID_IDispatch)
  167. {
  168. *ppvObj = (IRemoteMTScriptProxy *)this;
  169. }
  170. else if (iid == IID_IConnectionPointContainer)
  171. {
  172. *ppvObj = (IConnectionPointContainer *)this;
  173. }
  174. else if (iid == IID_IProvideClassInfo)
  175. {
  176. *ppvObj = (IProvideClassInfo *)this;
  177. }
  178. else
  179. {
  180. *ppvObj = NULL;
  181. return E_NOINTERFACE;
  182. }
  183. ((IUnknown *)*ppvObj)->AddRef();
  184. return S_OK;
  185. }
  186. //+---------------------------------------------------------------------------
  187. //
  188. // Member: CLocalMTProxy::AddRef, public
  189. //
  190. // Synopsis: Standard IUnknown::AddRef. Increments the refcount on the
  191. // CLocalMTProxy object.
  192. //
  193. //----------------------------------------------------------------------------
  194. ULONG
  195. CLocalMTProxy::AddRef()
  196. {
  197. return ++_ulRefs;
  198. }
  199. //+---------------------------------------------------------------------------
  200. //
  201. // Member: CLocalMTProxy::Release, public
  202. //
  203. // Synopsis: IUnknown::Release.
  204. //
  205. // Notes: If the refcount on CLocalMTProxy goes to zero, we know our
  206. // owner is done with us and we can clean up. So, we release
  207. // all our interface pointers and etc. However, someone may still
  208. // be holding on to our event sink subobject, so we can't
  209. // delete ourselves yet.
  210. //
  211. //----------------------------------------------------------------------------
  212. ULONG
  213. CLocalMTProxy::Release()
  214. {
  215. ULONG ulRefs = --_ulRefs;
  216. if (ulRefs == 0)
  217. {
  218. _ulRefs = ULREF_IN_DESTRUCTOR;
  219. Passivate();
  220. AssertSz(_ulRefs == ULREF_IN_DESTRUCTOR,
  221. "NONFATAL: Invalid refcount during passivate!");
  222. _ulRefs = 0;
  223. SubRelease();
  224. }
  225. return ulRefs;
  226. }
  227. //+---------------------------------------------------------------------------
  228. //
  229. // Member: CLocalMTProxy::SubAddRef, public
  230. //
  231. // Synopsis: Called when the event sink gets addref'd. Increments an overall
  232. // refcount.
  233. //
  234. //----------------------------------------------------------------------------
  235. ULONG
  236. CLocalMTProxy::SubAddRef()
  237. {
  238. return ++_ulAllRefs;
  239. }
  240. //+---------------------------------------------------------------------------
  241. //
  242. // Member: CLocalMTProxy::SubRelease, public
  243. //
  244. // Synopsis: Called when the event sink gets released and when
  245. // CLocalMTProxy passivates. If the overall refcount is zero,
  246. // we know no-one is using us and we can go away.
  247. //
  248. //----------------------------------------------------------------------------
  249. ULONG
  250. CLocalMTProxy::SubRelease()
  251. {
  252. if (--_ulAllRefs == 0)
  253. {
  254. _ulAllRefs = ULREF_IN_DESTRUCTOR;
  255. _ulRefs = ULREF_IN_DESTRUCTOR;
  256. delete this;
  257. }
  258. return 0;
  259. }
  260. //---------------------------------------------------------------------------
  261. //
  262. // Member: CLocalMTProxy::EnumConnectionPoints, IConnectionPointContainer
  263. //
  264. //---------------------------------------------------------------------------
  265. HRESULT
  266. CLocalMTProxy::EnumConnectionPoints(LPENUMCONNECTIONPOINTS *)
  267. {
  268. return E_NOTIMPL;
  269. }
  270. //---------------------------------------------------------------------------
  271. //
  272. // Member: CLocalMTProxy::FindConnectionPoint, IConnectionPointContainer
  273. //
  274. //---------------------------------------------------------------------------
  275. HRESULT
  276. CLocalMTProxy::FindConnectionPoint(REFIID iid, LPCONNECTIONPOINT* ppCpOut)
  277. {
  278. HRESULT hr;
  279. TraceTag((tagError, "CLocalMTProxy::FindConnectionPoint called."));
  280. if (iid == DIID_DRemoteMTScriptEvents || iid == IID_IDispatch)
  281. {
  282. TraceTag((tagError, "CLocalMTProxy::FindConnectionPoint: Returning event source."));
  283. *ppCpOut = new CLocalProxyCP(this);
  284. hr = *ppCpOut ? S_OK : E_OUTOFMEMORY;
  285. }
  286. else
  287. {
  288. hr = E_NOINTERFACE;
  289. }
  290. RRETURN(hr);
  291. }
  292. //+---------------------------------------------------------------------------
  293. //
  294. // Member: CLocalMTProxy::GetClassInfo, public
  295. //
  296. // Synopsis: Implementation of IProvideClassInfo
  297. //
  298. // Arguments: [pTI] -- Return type info interface here
  299. //
  300. // Notes: This returns the typeinfo for the RemoteMTScriptProxy coclass
  301. //
  302. //----------------------------------------------------------------------------
  303. HRESULT
  304. CLocalMTProxy::GetClassInfo(ITypeInfo **pTI)
  305. {
  306. HRESULT hr;
  307. TraceTag((tagError, "CLocalMTProxy::GetClassInfo called"));
  308. hr = LoadTypeLibs();
  309. if (hr)
  310. return hr;
  311. hr = _pTypeLibDLL->GetTypeInfoOfGuid(CLSID_RemoteMTScriptProxy, pTI);
  312. return hr;
  313. }
  314. //---------------------------------------------------------------------------
  315. //
  316. // Member: CLocalMTProxy::GetTypeInfo, IDispatch
  317. //
  318. // Notes: This returns the typeinfo for the IRemoteMTScriptProxy dual
  319. // interface.
  320. //
  321. //---------------------------------------------------------------------------
  322. HRESULT
  323. CLocalMTProxy::GetTypeInfo(UINT itinfo, ULONG lcid, ITypeInfo ** pptinfo)
  324. {
  325. HRESULT hr;
  326. TraceTag((tagError, "CLocalMTProxy::GetTypeInfo called"));
  327. hr = LoadTypeLibs();
  328. if (hr)
  329. return hr;
  330. *pptinfo = _pTypeInfoInterface;
  331. (*pptinfo)->AddRef();
  332. return S_OK;
  333. }
  334. //---------------------------------------------------------------------------
  335. //
  336. // Member: CLocalMTProxy::GetTypeInfoCount, IDispatch
  337. //
  338. //---------------------------------------------------------------------------
  339. HRESULT
  340. CLocalMTProxy::GetTypeInfoCount(UINT * pctinfo)
  341. {
  342. *pctinfo = 1;
  343. return S_OK;
  344. }
  345. //---------------------------------------------------------------------------
  346. //
  347. // Member: CLocalMTProxy::GetIDsOfNames, IDispatch
  348. //
  349. //---------------------------------------------------------------------------
  350. HRESULT
  351. CLocalMTProxy::GetIDsOfNames(REFIID riid, LPOLESTR * rgszNames, UINT cNames, LCID lcid, DISPID * rgdispid)
  352. {
  353. HRESULT hr;
  354. hr = LoadTypeLibs();
  355. if (hr)
  356. return hr;
  357. hr = _pTypeInfoInterface->GetIDsOfNames(rgszNames, cNames, rgdispid);
  358. if (hr && _pDispRemote)
  359. {
  360. hr = _pTypeInfoCM->GetIDsOfNames(rgszNames, cNames, rgdispid);
  361. }
  362. return hr;
  363. }
  364. //---------------------------------------------------------------------------
  365. //
  366. // Member: CLocalMTProxy::Invoke, IDispatch
  367. //
  368. //---------------------------------------------------------------------------
  369. HRESULT
  370. CLocalMTProxy::Invoke(DISPID dispidMember,
  371. REFIID riid,
  372. LCID lcid,
  373. WORD wFlags,
  374. DISPPARAMS * pdispparams,
  375. VARIANT * pvarResult,
  376. EXCEPINFO * pexcepinfo,
  377. UINT * puArgErr)
  378. {
  379. HRESULT hr;
  380. hr = LoadTypeLibs();
  381. if (hr)
  382. return hr;
  383. hr = _pTypeInfoInterface->Invoke((IRemoteMTScriptProxy *)this,
  384. dispidMember,
  385. wFlags,
  386. pdispparams,
  387. pvarResult,
  388. pexcepinfo,
  389. puArgErr);
  390. //
  391. // If we're connected to the remote object, then we forward any calls
  392. // we don't know how to handle on to that object. This is not aggregation,
  393. // since we have not set up object identity in this relationship.
  394. //
  395. if (hr && _pDispRemote)
  396. {
  397. hr = _pDispRemote->Invoke(dispidMember,
  398. riid,
  399. lcid,
  400. wFlags,
  401. pdispparams,
  402. pvarResult,
  403. pexcepinfo,
  404. puArgErr);
  405. }
  406. return hr;
  407. }
  408. //+---------------------------------------------------------------------------
  409. //
  410. // Member: CLocalMTProxy::LoadTypeLibs, public
  411. //
  412. // Synopsis: Ensures that we have loaded our typelibrary
  413. //
  414. //----------------------------------------------------------------------------
  415. HRESULT
  416. CLocalMTProxy::LoadTypeLibs()
  417. {
  418. HRESULT hr = S_OK;
  419. TCHAR achDll[MAX_PATH];
  420. if (!_pTypeLibDLL)
  421. {
  422. GetModuleFileName(g_hInstDll, achDll, MAX_PATH);
  423. hr = THR(LoadTypeLib(achDll, &_pTypeLibDLL));
  424. if (hr)
  425. goto Cleanup;
  426. }
  427. if (!_pTypeInfoInterface)
  428. {
  429. hr = THR(_pTypeLibDLL->GetTypeInfoOfGuid(IID_IRemoteMTScriptProxy,
  430. &_pTypeInfoInterface));
  431. if (hr)
  432. goto Cleanup;
  433. }
  434. if (!_pTypeInfoCM)
  435. {
  436. hr = THR(_pTypeLibDLL->GetTypeInfoOfGuid(IID_IConnectedMachine,
  437. &_pTypeInfoCM));
  438. if (hr)
  439. goto Cleanup;
  440. }
  441. Cleanup:
  442. if (hr)
  443. {
  444. TraceTag((tagError, "CLocalMTProxy::LoadTypeLibs returning %x", hr));
  445. }
  446. return hr;
  447. }
  448. // *************************************************************************
  449. //+---------------------------------------------------------------------------
  450. //
  451. // Member: CLocalMTProxy::Connect, public
  452. //
  453. // Synopsis: Connects to the RemoteMTScript object on the given remote
  454. // (or local) machine.
  455. //
  456. // Arguments: [bstrMachine] -- Machine to connect to. If NULL or empty,
  457. // use the local machine.
  458. //
  459. // Returns: HRESULT
  460. //
  461. // Notes: This also sets up the event sink for handling events.
  462. //
  463. //----------------------------------------------------------------------------
  464. STDMETHODIMP
  465. CLocalMTProxy::Connect(BSTR bstrMachine)
  466. {
  467. HRESULT hr = S_OK;
  468. COSERVERINFO csi = { 0 };
  469. MULTI_QI mqi[2] = { 0 };
  470. BOOL fRemote = TRUE;
  471. // IConnectionPointContainer *pCPC;
  472. // IConnectionPoint *pCP;
  473. if (!bstrMachine || SysStringLen(bstrMachine) == 0)
  474. {
  475. fRemote = FALSE;
  476. }
  477. TraceTag((tagError, "CLocalMTProxy::Connect called. Machine=%ls", (fRemote) ? bstrMachine : L"<local>"));
  478. // The following code will remove all security from the connection. This
  479. // will need to be enabled if the corresponding call to CoInitializeSecurity
  480. // is turned on in mtscript.exe.
  481. // Remove security for the connection.
  482. csi.pAuthInfo = NULL;
  483. csi.pwszName = bstrMachine;
  484. mqi[0].pIID = &IID_IDispatch;
  485. // mqi[1].pIID = &IID_IConnectionPointContainer;
  486. hr = CoCreateInstanceEx(CLSID_RemoteMTScript,
  487. NULL,
  488. CLSCTX_SERVER,
  489. (fRemote) ? &csi : NULL,
  490. 1,
  491. mqi);
  492. if (FAILED(hr))
  493. {
  494. TraceTag((tagError, "CLocalMTProxy::Connect: CoCreateInstanceEx returned=%x", hr));
  495. return hr;
  496. }
  497. if (mqi[0].hr)
  498. return mqi[0].hr;
  499. _pDispRemote = (IDispatch *)mqi[0].pItf;
  500. /*
  501. // Security problems make it difficult to impossible to make a
  502. // reverse COM event interface connect successfully.
  503. if (!mqi[1].hr)
  504. {
  505. pCPC = (IConnectionPointContainer *)mqi[1].pItf;
  506. hr = pCPC->FindConnectionPoint(DIID_DRemoteMTScriptEvents, &pCP);
  507. if (!hr)
  508. {
  509. hr = pCP->Advise(&_cesSink, &_dwSinkCookie);
  510. ReleaseInterface(pCP);
  511. }
  512. ReleaseInterface(pCPC);
  513. #if DBG == 1
  514. if (hr)
  515. TraceTag((tagError, "Hookup to event sink returned %x", hr));
  516. #endif
  517. // If the advise failed for some reason, just don't sink events.
  518. }
  519. else
  520. {
  521. TraceTag((tagError, "CLocalMTProxy::Connect: ICPC QI returned=%x", mqi[1].hr));
  522. }
  523. */
  524. return S_OK;
  525. }
  526. //+---------------------------------------------------------------------------
  527. //
  528. // Member: CLocalMTProxy::Disconnect, public
  529. //
  530. // Synopsis: Disconnects from a machine we connected to via Connect().
  531. //
  532. // Arguments: (none)
  533. //
  534. //----------------------------------------------------------------------------
  535. STDMETHODIMP
  536. CLocalMTProxy::Disconnect()
  537. {
  538. HRESULT hr = S_OK;
  539. TraceTag((tagError, "CLocalMTProxy::Disconnect called"));
  540. if (_dwSinkCookie)
  541. {
  542. IConnectionPointContainer *pCPC;
  543. IConnectionPoint *pCP;
  544. hr = _pDispRemote->QueryInterface(IID_IConnectionPointContainer, (LPVOID*)&pCPC);
  545. if (!hr)
  546. {
  547. hr = pCPC->FindConnectionPoint(DIID_DRemoteMTScriptEvents,
  548. &pCP);
  549. if (!hr)
  550. {
  551. pCP->Unadvise(_dwSinkCookie);
  552. ReleaseInterface(pCP);
  553. }
  554. ReleaseInterface(pCPC);
  555. #if DBG == 1
  556. if (hr)
  557. TraceTag((tagError, "Unadvise from event sink returned %x", hr));
  558. #endif
  559. }
  560. _dwSinkCookie = 0;
  561. }
  562. ClearInterface(&_pDispRemote);
  563. return S_OK;
  564. }
  565. //+---------------------------------------------------------------------------
  566. //
  567. // Member: CLocalMTProxy::DownloadFile, public
  568. //
  569. // Synopsis: Downloads a file from the given URL and stores it locally.
  570. //
  571. // Arguments: [bstrURL] -- URL to download
  572. // [bstrFile] -- Path of where the file was saved by urlmon
  573. //
  574. // Returns: HRESULT
  575. //
  576. //----------------------------------------------------------------------------
  577. STDMETHODIMP
  578. CLocalMTProxy::DownloadFile(BSTR bstrURL, BSTR *bstrFile)
  579. {
  580. HRESULT hr;
  581. TCHAR achBuf[MAX_PATH * 2];
  582. hr = URLDownloadToCacheFile((IRemoteMTScriptProxy*)this,
  583. bstrURL,
  584. achBuf,
  585. MAX_PATH * 2,
  586. 0,
  587. NULL);
  588. if (hr)
  589. {
  590. int cChar;
  591. HINSTANCE hModURLMON = LoadLibraryA("urlmon.dll");
  592. cChar = wsprintf(achBuf, L"Error: (%x) ", hr);
  593. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
  594. FORMAT_MESSAGE_FROM_HMODULE |
  595. FORMAT_MESSAGE_IGNORE_INSERTS,
  596. hModURLMON,
  597. hr,
  598. 0,
  599. achBuf + cChar,
  600. MAX_PATH * 2 - cChar,
  601. NULL);
  602. FreeLibrary(hModURLMON);
  603. }
  604. *bstrFile = SysAllocString(achBuf);
  605. return S_OK;
  606. }
  607. // *************************************************************************
  608. //
  609. // CMTEventSink
  610. //
  611. // Class which implements the event sink for the remote object. This just
  612. // forwards all calls to the event sink registered with us by the web page,
  613. // if any.
  614. //
  615. // *************************************************************************
  616. HRESULT
  617. CMTEventSink::QueryInterface(REFIID iid, void **ppv)
  618. {
  619. if (iid == IID_IUnknown || iid == IID_IDispatch)
  620. {
  621. *ppv = (IDispatch *)this;
  622. }
  623. else
  624. {
  625. *ppv = NULL;
  626. return E_NOINTERFACE;
  627. }
  628. ((IUnknown *)*ppv)->AddRef();
  629. return S_OK;
  630. }
  631. //---------------------------------------------------------------------------
  632. //
  633. // Member: CMTEventSink::GetTypeInfo, IDispatch
  634. //
  635. //---------------------------------------------------------------------------
  636. HRESULT
  637. CMTEventSink::GetTypeInfo(UINT itinfo, ULONG lcid, ITypeInfo ** pptinfo)
  638. {
  639. if (Proxy()->_pDispSink)
  640. {
  641. return Proxy()->_pDispSink->GetTypeInfo(itinfo, lcid, pptinfo);
  642. }
  643. return S_OK;
  644. }
  645. //---------------------------------------------------------------------------
  646. //
  647. // Member: CMTEventSink::GetTypeInfoCount, IDispatch
  648. //
  649. //---------------------------------------------------------------------------
  650. HRESULT
  651. CMTEventSink::GetTypeInfoCount(UINT * pctinfo)
  652. {
  653. if (Proxy()->_pDispSink)
  654. {
  655. return Proxy()->_pDispSink->GetTypeInfoCount(pctinfo);
  656. }
  657. return S_OK;
  658. }
  659. //---------------------------------------------------------------------------
  660. //
  661. // Member: CMTEventSink::GetIDsOfNames, IDispatch
  662. //
  663. //---------------------------------------------------------------------------
  664. HRESULT
  665. CMTEventSink::GetIDsOfNames(REFIID riid,
  666. LPOLESTR * rgszNames,
  667. UINT cNames,
  668. LCID lcid,
  669. DISPID * rgdispid)
  670. {
  671. if (Proxy()->_pDispSink)
  672. {
  673. return Proxy()->_pDispSink->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
  674. }
  675. return S_OK;
  676. }
  677. //---------------------------------------------------------------------------
  678. //
  679. // Member: CMTEventSink::Invoke, IDispatch
  680. //
  681. //---------------------------------------------------------------------------
  682. HRESULT
  683. CMTEventSink::Invoke(DISPID dispidMember,
  684. REFIID riid,
  685. LCID lcid,
  686. WORD wFlags,
  687. DISPPARAMS * pdispparams,
  688. VARIANT * pvarResult,
  689. EXCEPINFO * pexcepinfo,
  690. UINT * puArgErr)
  691. {
  692. TraceTag((tagError, "CMTEventSink::Invoke called"));
  693. if (Proxy()->_pDispSink)
  694. {
  695. HRESULT hr;
  696. hr = Proxy()->_pDispSink->Invoke(dispidMember,
  697. riid,
  698. lcid,
  699. wFlags,
  700. pdispparams,
  701. pvarResult,
  702. pexcepinfo,
  703. puArgErr);
  704. if (hr)
  705. {
  706. TraceTag((tagError, "CMTEventSink::Invoke: Sink call returned %x!", hr));
  707. }
  708. }
  709. TraceTag((tagError, "CMTEventSink::Invoke returning"));
  710. return S_OK;
  711. }