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.

181 lines
4.4 KiB

  1. // Copyright (c) 1999 Microsoft Corporation. All rights reserved.
  2. //
  3. // Implementation of CAutBaseImp.
  4. //
  5. #include "dll.h"
  6. //////////////////////////////////////////////////////////////////////
  7. // Creation
  8. template <class T_derived, class T_ITarget, const IID *T_piid>
  9. CAutBaseImp<T_derived, T_ITarget, T_piid>::CAutBaseImp(
  10. IUnknown* pUnknownOuter,
  11. const IID& iid,
  12. void** ppv,
  13. HRESULT *phr)
  14. : m_pITarget(NULL)
  15. {
  16. struct LocalFunc
  17. {
  18. static HRESULT CheckParams(IUnknown* pUnknownOuter, void** ppv)
  19. {
  20. V_INAME(CAutBaseImp::CAutBaseImp);
  21. V_INTERFACE(pUnknownOuter);
  22. V_PTR_WRITE(ppv, IUnknown *);
  23. return S_OK;
  24. }
  25. };
  26. *phr = LocalFunc::CheckParams(pUnknownOuter, ppv);
  27. if (FAILED(*phr))
  28. return;
  29. *ppv = NULL;
  30. // This class can only be created inside an aggregation.
  31. if (!pUnknownOuter || iid != IID_IUnknown)
  32. {
  33. Trace(1, "Error: The AutoImp objects are used by other DirectMusic objects, but are not designed to be instantiated on their own.\n");
  34. *phr = E_INVALIDARG;
  35. return;
  36. }
  37. // The outer object must have the target interface.
  38. *phr = pUnknownOuter->QueryInterface(*T_piid, reinterpret_cast<void**>(&m_pITarget));
  39. if (FAILED(*phr))
  40. return;
  41. // Due to the aggregation contract, our object is wholely contained in the lifetime of
  42. // the outer object and we shouldn't hold any references to it.
  43. ULONG ulCheck = m_pITarget->Release();
  44. assert(ulCheck);
  45. m_UnkControl.Init(this, this);
  46. LockModule(true);
  47. *phr = m_UnkControl.QueryInterface(iid, ppv);
  48. return;
  49. }
  50. //////////////////////////////////////////////////////////////////////
  51. // IUnknown
  52. // Delegates to outer unknown.
  53. template <class T_derived, class T_ITarget, const IID *T_piid>
  54. STDMETHODIMP
  55. CAutBaseImp<T_derived, T_ITarget, T_piid>::QueryInterface(const IID &iid, void **ppv)
  56. {
  57. return m_pITarget->QueryInterface(iid, ppv);
  58. }
  59. template <class T_derived, class T_ITarget, const IID *T_piid>
  60. STDMETHODIMP_(ULONG)
  61. CAutBaseImp<T_derived, T_ITarget, T_piid>::AddRef()
  62. {
  63. return m_pITarget->AddRef();
  64. }
  65. template <class T_derived, class T_ITarget, const IID *T_piid>
  66. STDMETHODIMP_(ULONG)
  67. CAutBaseImp<T_derived, T_ITarget, T_piid>::Release()
  68. {
  69. return m_pITarget->Release();
  70. }
  71. //////////////////////////////////////////////////////////////////////
  72. // Private Functions
  73. template <class T_derived, class T_ITarget, const IID *T_piid>
  74. void
  75. CAutBaseImp<T_derived, T_ITarget, T_piid>::Destroy()
  76. {
  77. LockModule(false);
  78. delete this;
  79. }
  80. //////////////////////////////////////////////////////////////////////
  81. // IDispatch
  82. template <class T_derived, class T_ITarget, const IID *T_piid>
  83. STDMETHODIMP
  84. CAutBaseImp<T_derived, T_ITarget, T_piid>::GetTypeInfoCount(UINT *pctinfo)
  85. {
  86. V_INAME(CAutBaseImp::GetTypeInfoCount);
  87. V_PTR_WRITE(pctinfo, UINT);
  88. *pctinfo = 0;
  89. return S_OK;
  90. }
  91. template <class T_derived, class T_ITarget, const IID *T_piid>
  92. STDMETHODIMP
  93. CAutBaseImp<T_derived, T_ITarget, T_piid>::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo __RPC_FAR *__RPC_FAR *ppTInfo)
  94. {
  95. *ppTInfo = NULL;
  96. return E_NOTIMPL;
  97. }
  98. template <class T_derived, class T_ITarget, const IID *T_piid>
  99. STDMETHODIMP
  100. CAutBaseImp<T_derived, T_ITarget, T_piid>::GetIDsOfNames(
  101. REFIID riid,
  102. LPOLESTR __RPC_FAR *rgszNames,
  103. UINT cNames,
  104. LCID lcid,
  105. DISPID __RPC_FAR *rgDispId)
  106. {
  107. return AutDispatchGetIDsOfNames(T_derived::ms_Methods, riid, rgszNames, cNames, lcid, rgDispId);
  108. }
  109. template <class T_derived, class T_ITarget, const IID *T_piid>
  110. STDMETHODIMP
  111. CAutBaseImp<T_derived, T_ITarget, T_piid>::Invoke(
  112. DISPID dispIdMember,
  113. REFIID riid,
  114. LCID lcid,
  115. WORD wFlags,
  116. DISPPARAMS __RPC_FAR *pDispParams,
  117. VARIANT __RPC_FAR *pVarResult,
  118. EXCEPINFO __RPC_FAR *pExcepInfo,
  119. UINT __RPC_FAR *puArgErr)
  120. {
  121. // Decode the parameters
  122. AutDispatchDecodedParams addp;
  123. HRESULT hr = AutDispatchInvokeDecode(
  124. T_derived::ms_Methods,
  125. &addp,
  126. dispIdMember,
  127. riid,
  128. lcid,
  129. wFlags,
  130. pDispParams,
  131. pVarResult,
  132. puArgErr,
  133. T_derived::ms_wszClassName,
  134. m_pITarget);
  135. if (FAILED(hr))
  136. return hr;
  137. // Call the handler
  138. for (const DispatchHandlerEntry<T_derived> *pdhe = T_derived::ms_Handlers;
  139. pdhe->dispid != DISPID_UNKNOWN && pdhe->dispid != dispIdMember;
  140. ++pdhe)
  141. {
  142. }
  143. if (pdhe->dispid == DISPID_UNKNOWN)
  144. {
  145. assert(false);
  146. return DISP_E_MEMBERNOTFOUND;
  147. }
  148. hr = ((static_cast<T_derived*>(this))->*pdhe->pmfn)(&addp);
  149. // Clean up and return
  150. AutDispatchInvokeFree(T_derived::ms_Methods, &addp, dispIdMember, riid);
  151. return AutDispatchHrToException(T_derived::ms_Methods, dispIdMember, riid, hr, pExcepInfo);
  152. }