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.

195 lines
5.6 KiB

  1. // ITUnk.h -- Base level IUnknown interface used by objects in this DLL
  2. #ifndef __ITUNK_H__
  3. #define __ITUNK_H__
  4. // The CITUnknown class takes care of object reference counting for all
  5. // the objects we create in this DLL. This means that all of our base
  6. // level IUnknown interfaces must inherit from this class.
  7. //
  8. // Since we don't define an implementation for QueryInterface, this class
  9. // cannot be used by itself.
  10. //
  11. // This class does nothing for standard interfaces derrived indirectly
  12. // from IUnknown (IStorage, IStream, ...).
  13. // The Guid_Parts define is a tool for building constant arrays of IID's.
  14. #define Guid_Parts(guid) guid.Data1, guid.Data2, guid.Data3, \
  15. guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], \
  16. guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]
  17. typedef IUnknown *PUnknown;
  18. class CITUnknown : public IUnknown
  19. {
  20. public:
  21. // CITUnknown();
  22. CITUnknown(const IID *paIID, UINT cIID, IUnknown * pIFace);
  23. CITUnknown(const IID *paIID, UINT cIID, IUnknown **papIFace);
  24. static void CloseActiveObjects();
  25. void MoveInFrontOf(CITUnknown *pITUnk);
  26. void MarkSecondary();
  27. BOOL IsSecondary();
  28. virtual ~CITUnknown() = 0; // The destructor has to be virtual so that the
  29. // proper destructor is called for each subclass
  30. // of CITUnknown.
  31. STDMETHODIMP_(ULONG) AddRef (void);
  32. STDMETHODIMP_(ULONG) Release(void);
  33. STDMETHODIMP QueryInterface(REFIID riid, PPVOID ppv);
  34. #ifdef _DEBUG
  35. static void OpenReferee(void);
  36. static void CloseReferee(void);
  37. #endif // _DEBUG
  38. static HRESULT FinishSetup(HRESULT hr, CITUnknown *pUnk, REFIID riid, PPVOID ppv);
  39. static CITCriticalSection s_csUnk;
  40. // DEBUGDEF(static CITCriticalSection s_csUnk)
  41. private:
  42. void CommonInitialing();
  43. void Uncouple();
  44. LONG m_cRefs;
  45. const IID *m_paIID;
  46. UINT m_cIID;
  47. IUnknown *m_pIFace;
  48. IUnknown **m_papIFace;
  49. BOOL m_fAlreadyDead;
  50. BOOL m_fSecondary;
  51. CITUnknown *m_pitunkPrev;
  52. CITUnknown *m_pitunkNext;
  53. // DEBUGDEF(CITUnknown *m_pitunkNext)
  54. DEBUGDEF(static BOOL s_fCSInitialed)
  55. static CITUnknown *s_pitunkActive;
  56. // DEBUGDEF(static CITUnknown *s_pitunkActive)
  57. };
  58. typedef CITUnknown *PITUnknown;
  59. inline void CITUnknown::MarkSecondary()
  60. {
  61. m_fSecondary = TRUE;
  62. }
  63. inline BOOL CITUnknown::IsSecondary()
  64. {
  65. return m_fSecondary;
  66. }
  67. // DEBUGDEF(extern PITUnknown CITUnknown::m_pitunkActive)
  68. // The class CImpITUnknown will be used as one of the base classes defining
  69. // the imbedded implementation which rely on CITUnknown for aggregation logic.
  70. //
  71. // The pattern here is that the outer class derived from CITUnknown will have
  72. // a constructor of the form:
  73. //
  74. // CMyObject::CMyObject(IUnknown *punkOuter) :
  75. // m_ImpIObject(this, punkOuter)
  76. // {
  77. // // Initialing code for CMyObject goes here...
  78. // }
  79. //
  80. // Where m_ImpIObject is a member variable of CMyObject which has been derived
  81. // from CImpITUnknown where CImpITUnknown has a constructor of the form:
  82. //
  83. // CMyObject::CImpIMyObject::CImpIMyObject(CITUnknown *pBackObj, IUnknown *punkOuter)
  84. // : CImpITUnknown(pBackObj, punkOuter)
  85. // {
  86. // // Initialing code for CImpIMyObject goes here...
  87. // }
  88. //
  89. // If the derrivation is indirect, you must define constructors for every class in the
  90. // derivation chain to pass the pBackObj and punkOuter parameters down to CImpITUnknown.
  91. class CImpITUnknown;
  92. typedef CImpITUnknown *PCImpITUnknown;
  93. class CImpITUnknown : public IUnknown
  94. {
  95. public:
  96. CImpITUnknown(void);
  97. CImpITUnknown(CITUnknown *pBackObj, IUnknown *punkOuter);
  98. ~CImpITUnknown();
  99. STDMETHODIMP_(ULONG) AddRef (void);
  100. STDMETHODIMP_(ULONG) Release(void);
  101. STDMETHODIMP QueryInterface(REFIID riid, PPVOID ppv);
  102. CITUnknown *Container();
  103. BOOL HasControllingUnknown();
  104. IUnknown * ControllingIUnknown();
  105. BOOL ActiveMark();
  106. void MarkActive (PCImpITUnknown &pListStart);
  107. void MarkInactive();
  108. static void DetachReference(PCImpITUnknown &pITUnk);
  109. CImpITUnknown *NextObject();
  110. private:
  111. IUnknown *m_pUnkOuter;
  112. CITUnknown *m_pBackObj;
  113. BOOL m_fControlled;
  114. CImpITUnknown *m_pImpITUnknownNext;
  115. CImpITUnknown **m_ppImpITUnknownList;
  116. BOOL m_fActive;
  117. };
  118. // The DetachRef define verifies that the target pointer variable has
  119. // a type derived from PCImpITUnknown and then call DetachReference
  120. // to safely disconnect the variable and decrement our reference count.
  121. // Note that you still have to worry about multithreading cases. That
  122. // is, you must avoid race conditions between two threads which try
  123. // release the same pointer simultaneously. In practice the way to
  124. // deal with that problem is to have all objects owned by a single
  125. // thread and avoid the race condition.
  126. #define DetachRef(p) { \
  127. DEBUGDEF(PCImpITUnknown pUnk = p); \
  128. CImpITUnknown::DetachReference((PCImpITUnknown) p); \
  129. }
  130. inline BOOL CImpITUnknown::HasControllingUnknown()
  131. {
  132. return m_fControlled;
  133. }
  134. inline CImpITUnknown::CImpITUnknown(void) { RonM_ASSERT(FALSE); }
  135. inline IUnknown *CImpITUnknown::ControllingIUnknown()
  136. {
  137. return m_pUnkOuter;
  138. }
  139. inline BOOL CImpITUnknown::ActiveMark() { return m_fActive; }
  140. inline CImpITUnknown *CImpITUnknown::NextObject()
  141. {
  142. RonM_ASSERT(m_fActive);
  143. return m_pImpITUnknownNext;
  144. }
  145. inline CITUnknown *CImpITUnknown::Container()
  146. {
  147. return m_pBackObj;
  148. }
  149. #endif // __ITUNK_H__