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.

219 lines
5.0 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. pftn.h
  5. Abstract:
  6. Thread neutral COM ptrs. This is stolen from dmassare's MPC_COM.h file
  7. pretty much intact (with tracing & some stylistic changes added in)
  8. Revision History:
  9. created derekm 04/12/00
  10. ******************************************************************************/
  11. #ifndef PFTN_H
  12. #define PFTN_H
  13. #include "util.h"
  14. /////////////////////////////////////////////////////////////////////////////
  15. // global vars
  16. class CPFModule;
  17. extern CPFModule _PFModule;
  18. /////////////////////////////////////////////////////////////////////////////
  19. // CComPtrThreadNeutral_GIT
  20. // Class used to act as an hub for all the instances of CComPtrThreadNeutral<T>.
  21. // It holds the Global Interface Table.
  22. class CPFComPtrThreadNeutral_GIT
  23. {
  24. // member data
  25. IGlobalInterfaceTable *m_pGIT;
  26. CRITICAL_SECTION m_cs;
  27. // private member fns
  28. HRESULT GetGIT(IGlobalInterfaceTable **ppGIT);
  29. void Lock(void);
  30. void Unlock(void);
  31. public:
  32. CPFComPtrThreadNeutral_GIT(void);
  33. ~CPFComPtrThreadNeutral_GIT(void);
  34. HRESULT Init(void);
  35. HRESULT Term(void);
  36. HRESULT RegisterInterface(IUnknown *pUnk, REFIID riid, DWORD *pdwCookie);
  37. HRESULT RevokeInterface(DWORD dwCookie);
  38. HRESULT GetInterface(DWORD dwCookie, REFIID riid, LPVOID *ppv);
  39. };
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CComPtrThreadNeutral
  42. // This smart pointer template stores THREAD-INDEPEDENT pointers to COM objects.
  43. // The best way to use it is to store an object reference into it and then assign
  44. // the object itself to a CComPtr<T>.
  45. // This way the proper proxy is looked up and the smart pointer will keep it alive.
  46. template <class T> class CPFComPtrThreadNeutral
  47. {
  48. private:
  49. // member data
  50. DWORD m_dwCookie;
  51. // private fns
  52. void InnerRegister(T *lp)
  53. {
  54. if (lp != NULL)
  55. _PFModule.m_GITHolder.RegisterInterface(lp, __uuidof(T), &m_dwCookie);
  56. }
  57. public:
  58. typedef T _PtrClass;
  59. //////////////////////////////////////////////////////////////////////
  60. CPFComPtrThreadNeutral(void)
  61. {
  62. m_dwCookie = 0xFEFEFEFE;
  63. }
  64. CPFComPtrThreadNeutral(T *lp)
  65. {
  66. m_dwCookie = 0xFEFEFEFE;
  67. this->InnerRegister(lp);
  68. }
  69. ~CPFComPtrThreadNeutral(void)
  70. {
  71. this->Release();
  72. }
  73. //////////////////////////////////////////////////////////////////////
  74. operator CComPtr<T>() const
  75. {
  76. CComPtr<T> res;
  77. (void)this->Access(&res);
  78. return res;
  79. }
  80. CComPtr<T> operator=(T *lp)
  81. {
  82. this->Release();
  83. this->InnerRegister(lp);
  84. return (CComPtr<T>)(*this);
  85. }
  86. bool operator!() const
  87. {
  88. return (m_dwCookie == 0xFEFEFEFE);
  89. }
  90. //////////////////////////////////////////////////////////////////////
  91. void Release(void)
  92. {
  93. if (m_dwCookie != 0xFEFEFEFE)
  94. {
  95. _PFModule.m_GITHolder.RevokeInterface(m_dwCookie);
  96. m_dwCookie = 0xFEFEFEFE;
  97. }
  98. }
  99. void Attach(T *p)
  100. {
  101. *this = p;
  102. if (p != NULL)
  103. p->Release();
  104. }
  105. T *Detach(void)
  106. {
  107. T *pt;
  108. (void)this->Access(&pt);
  109. this->Release();
  110. return pt;
  111. }
  112. HRESULT Access(T **ppt) const
  113. {
  114. HRESULT hr;
  115. if (ppt == NULL)
  116. {
  117. hr = E_POINTER;
  118. }
  119. else
  120. {
  121. *ppt = NULL;
  122. if (m_dwCookie != 0xFEFEFEFE)
  123. hr = _PFModule.m_GITHolder.GetInterface(m_dwCookie,
  124. __uuidof(T),
  125. (void**)ppt);
  126. else
  127. hr = S_FALSE;
  128. }
  129. return hr;
  130. }
  131. };
  132. /////////////////////////////////////////////////////////////////////////////
  133. // CPFCallItem
  134. class CPFCallItem
  135. {
  136. public:
  137. CPFComPtrThreadNeutral<IDispatch> m_Dispatch;
  138. CPFComPtrThreadNeutral<IUnknown> m_Unknown;
  139. CComVariant m_Other;
  140. VARTYPE m_vt;
  141. CPFCallItem(void);
  142. CPFCallItem& operator=(const CComVariant& var);
  143. operator CComVariant() const;
  144. };
  145. /////////////////////////////////////////////////////////////////////////////
  146. // CPFCallDesc
  147. class CPFCallDesc
  148. {
  149. CPFComPtrThreadNeutral<IDispatch> m_dispTarget;
  150. CPFCallItem *m_rgciVars;
  151. DISPID m_dispidMethod;
  152. DWORD m_dwVars;
  153. public:
  154. CPFCallDesc(void);
  155. ~CPFCallDesc(void);
  156. HRESULT Init(IDispatch *dispTarget, DISPID dispidMethod,
  157. const CComVariant *rgvVars, int dwVars);
  158. HRESULT Call(void);
  159. };
  160. /////////////////////////////////////////////////////////////////////////////
  161. // CPFModule
  162. class CPFModule
  163. {
  164. public:
  165. CPFComPtrThreadNeutral_GIT m_GITHolder;
  166. HRESULT Init(void);
  167. HRESULT Term(void);
  168. };
  169. #endif