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.

211 lines
6.8 KiB

  1. #pragma once
  2. //
  3. // Macro to delegate IDispatch to base class. Needed so that CMarsBehaviorSite vtbl works -
  4. // the only other way to do this is make CMarsBehaviorSite and CMarsBehaviorFor templated classes
  5. //
  6. #define IMPLEMENT_IDISPATCH_DELEGATE_TO_BASE(BaseClass) \
  7. STDMETHOD(GetTypeInfoCount)(UINT* pctinfo) \
  8. { return BaseClass::GetTypeInfoCount(pctinfo); } \
  9. STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) \
  10. { return BaseClass::GetTypeInfo(itinfo, lcid, pptinfo); } \
  11. STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames, \
  12. LCID lcid, DISPID* rgdispid) \
  13. { return BaseClass::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid); } \
  14. STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid, \
  15. LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, \
  16. EXCEPINFO* pexcepinfo, UINT* puArgErr) \
  17. { return BaseClass::Invoke(dispidMember, riid, lcid, wFlags, \
  18. pdispparams, pvarResult, pexcepinfo, puArgErr); }
  19. //---------------------------------------------------------------------------------
  20. // CMarsComObject provides some functionality used by all or most Mars com objects
  21. // including addref/release and passivation
  22. // Exposed methods should be protected to ensure that they're not called while the
  23. // object is passive. There are three types of passivation protection:
  24. // if (VerifyNotPassive()) - this function should not be called while passive,
  25. // but we still want to protect against it
  26. // if (IsPassive()) - this function may be called while passive,
  27. // but we want to protect against it
  28. // ASSERT(!IsPassive()); - we're pretty sure this won't be called while passive,
  29. // but we want to detect it if it starts happening
  30. // Use:
  31. // derive from CMarsComObject
  32. // IMPLEMENT_ADDREF_RELEASE in source file
  33. // Implement DoPassivate()
  34. // Use IsPassive() and VerifyNotPassive() where appropriate
  35. // Don't call "delete" directly
  36. // CYourClass->Passivate() should be called before CYourClass->Release()
  37. // TODO: FENTER on Passivate() causes debug link warnings due to dupe functions
  38. class CMarsComObject
  39. {
  40. protected:
  41. LONG m_cRef;
  42. BOOL m_fPassive;
  43. protected:
  44. virtual ~CMarsComObject() { ATLASSERT(IsPassive()); ATLASSERT(m_cRef==0); }
  45. CMarsComObject() { m_cRef = 1; }
  46. ULONG InternalAddRef()
  47. {
  48. return ++m_cRef;
  49. }
  50. ULONG InternalRelease()
  51. {
  52. if (--m_cRef)
  53. {
  54. return m_cRef;
  55. }
  56. delete this;
  57. return 0;
  58. }
  59. inline BOOL VerifyNotPassive(HRESULT *phr=NULL)
  60. {
  61. if (IsPassive())
  62. {
  63. if (phr)
  64. {
  65. *phr = SCRIPT_ERROR;
  66. }
  67. return FALSE;
  68. }
  69. return TRUE;
  70. }
  71. inline HRESULT GetBSTROut(const BSTR &bstrParam, BSTR *pbstrOut)
  72. {
  73. HRESULT hr = E_UNEXPECTED;
  74. ATLASSERT(API_IsValidBstr(bstrParam));
  75. if (API_IsValidWritePtr(pbstrOut))
  76. {
  77. if (VerifyNotPassive(&hr))
  78. {
  79. *pbstrOut = ::SysAllocStringLen(bstrParam,
  80. ::SysStringLen(bstrParam));
  81. hr = (*pbstrOut) ? S_OK : E_OUTOFMEMORY;
  82. }
  83. else
  84. {
  85. *pbstrOut = NULL;
  86. }
  87. }
  88. return hr;
  89. }
  90. virtual HRESULT DoPassivate() = 0;
  91. public:
  92. BOOL IsPassive() { return m_fPassive; }
  93. virtual HRESULT Passivate()
  94. {
  95. if (!IsPassive())
  96. {
  97. m_fPassive=TRUE;
  98. return DoPassivate();
  99. }
  100. else
  101. {
  102. return S_FALSE;
  103. }
  104. }
  105. };
  106. #define IMPLEMENT_ADDREF_RELEASE(cls) \
  107. STDMETHODIMP_(ULONG) cls::AddRef() \
  108. { \
  109. return InternalAddRef(); \
  110. } \
  111. \
  112. STDMETHODIMP_(ULONG) cls::Release() \
  113. { \
  114. return InternalRelease(); \
  115. }
  116. #define FAIL_AFTER_PASSIVATE() if(IsPassive()) { ATLASSERT(0); return E_FAIL; }
  117. //---------------------------------------------------------------------------------
  118. // CMarsComObjectDelegate is used by objects which are completely contained within
  119. // another object. They delegate their lifetime to the other object and are
  120. // passivated when the parent is passivated.
  121. // Use:
  122. // derive from CMarsComObjectDelegate<ParentClass>
  123. // IMPLEMENT_ADDREF_RELEASE in source file
  124. // Implement DoPassivate()
  125. // Use IsPassive() and VerifyNotPassive() where appropriate
  126. // Use Parent() to access the parent object
  127. template <class clsDelegateTo> class CMarsComObjectDelegate
  128. {
  129. clsDelegateTo *m_pParent;
  130. // DEBUG_ONLY(BOOL m_fPassivateCalled);
  131. protected:
  132. virtual ~CMarsComObjectDelegate() { ATLASSERT(m_fPassivateCalled); }
  133. CMarsComObjectDelegate(clsDelegateTo *pParent)
  134. {
  135. ATLASSERT(pParent);
  136. m_pParent = pParent;
  137. }
  138. ULONG InternalAddRef() { return m_pParent->AddRef(); }
  139. ULONG InternalRelease() { return m_pParent->Release(); }
  140. clsDelegateTo *Parent() { ATLASSERT(!IsPassive()); return m_pParent; }
  141. inline BOOL VerifyNotPassive(HRESULT *phr=NULL)
  142. {
  143. ATLASSERT(m_fPassivateCalled == IsPassive());
  144. if (m_pParent->IsPassive())
  145. {
  146. if (phr)
  147. {
  148. *phr = SCRIPT_ERROR;
  149. }
  150. return FALSE;
  151. }
  152. return TRUE;
  153. }
  154. virtual HRESULT DoPassivate() = 0;
  155. public:
  156. BOOL IsPassive() { return m_pParent->IsPassive(); }
  157. private:
  158. friend clsDelegateTo;
  159. HRESULT Passivate()
  160. {
  161. // TODO: assert that we are being called by our parent's DoPassivate
  162. ATLASSERT(m_fPassivateCalled==FALSE);
  163. //DEBUG_ONLY(m_fPassivateCalled=TRUE);
  164. return DoPassivate();
  165. }
  166. };
  167. // This typedef's some CxxxSubObject types to make syntax easier
  168. #define TYPEDEF_SUB_OBJECT(cls) typedef CMarsComObjectDelegate<class cls> cls##SubObject;