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.

350 lines
8.7 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. pftn.cpp
  5. Abstract:
  6. Thread neutral COM ptrs. This is stolen from dmassare's MPC_Common class
  7. pretty much intact (with tracing & some stylistic changes added in)
  8. Revision History:
  9. created derekm 04/12/00
  10. ******************************************************************************/
  11. #include "stdafx.h"
  12. #include "pftn.h"
  13. #include <process.h>
  14. /////////////////////////////////////////////////////////////////////////////
  15. // tracing
  16. #ifdef THIS_FILE
  17. #undef THIS_FILE
  18. #endif
  19. static char __szTraceSourceFile[] = __FILE__;
  20. #define THIS_FILE __szTraceSourceFile
  21. /////////////////////////////////////////////////////////////////////////////
  22. // CPFComPtrThreadNeutral_GIT construct / term
  23. // **************************************************************************
  24. CPFComPtrThreadNeutral_GIT::CPFComPtrThreadNeutral_GIT(void)
  25. {
  26. m_pGIT = NULL;
  27. ::InitializeCriticalSection(&m_cs);
  28. }
  29. // **************************************************************************
  30. CPFComPtrThreadNeutral_GIT::~CPFComPtrThreadNeutral_GIT(void)
  31. {
  32. this->Term();
  33. ::DeleteCriticalSection(&m_cs);
  34. }
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CPFComPtrThreadNeutral_GIT exposed
  37. // **************************************************************************
  38. void CPFComPtrThreadNeutral_GIT::Lock(void)
  39. {
  40. ::EnterCriticalSection(&m_cs);
  41. }
  42. // **************************************************************************
  43. void CPFComPtrThreadNeutral_GIT::Unlock(void)
  44. {
  45. ::LeaveCriticalSection(&m_cs);
  46. }
  47. // **************************************************************************
  48. HRESULT CPFComPtrThreadNeutral_GIT::GetGIT(IGlobalInterfaceTable **ppGIT)
  49. {
  50. USE_TRACING("CPFComPtrThreadNeutral_GIT::GetGIT");
  51. // this will automatcially unlock when the fn exits
  52. CAutoUnlockCS aucs(&m_cs);
  53. HRESULT hr = NOERROR;
  54. VALIDATEPARM(hr, (ppGIT == NULL));
  55. if (FAILED(hr))
  56. goto done;
  57. aucs.Lock();
  58. VALIDATEEXPR(hr, (m_pGIT == NULL), E_FAIL);
  59. if (FAILED(hr))
  60. goto done;
  61. if (*ppGIT = m_pGIT)
  62. {
  63. m_pGIT->AddRef();
  64. hr = NOERROR;
  65. }
  66. aucs.Unlock();
  67. done:
  68. return hr;
  69. }
  70. // **************************************************************************
  71. HRESULT CPFComPtrThreadNeutral_GIT::Init(void)
  72. {
  73. USE_TRACING("CPFComPtrThreadNeutral_GIT::Init");
  74. HRESULT hr = NOERROR;
  75. this->Lock();
  76. if (m_pGIT == NULL)
  77. {
  78. TESTHR(hr, CoCreateInstance(CLSID_StdGlobalInterfaceTable, NULL,
  79. CLSCTX_INPROC_SERVER,
  80. IID_IGlobalInterfaceTable,
  81. (LPVOID *)&m_pGIT));
  82. }
  83. this->Unlock();
  84. return hr;
  85. }
  86. // **************************************************************************
  87. HRESULT CPFComPtrThreadNeutral_GIT::Term(void)
  88. {
  89. USE_TRACING("CPFComPtrThreadNeutral_GIT::Term");
  90. HRESULT hr = NOERROR;
  91. this->Lock();
  92. if (m_pGIT != NULL)
  93. {
  94. m_pGIT->Release();
  95. m_pGIT = NULL;
  96. }
  97. this->Unlock();
  98. return hr;
  99. }
  100. // **************************************************************************
  101. HRESULT CPFComPtrThreadNeutral_GIT::RegisterInterface(IUnknown *pUnk,
  102. REFIID riid,
  103. DWORD *pdwCookie)
  104. {
  105. USE_TRACING("CPFComPtrThreadNeutral_GIT::RegisterInterface");
  106. CComPtr<IGlobalInterfaceTable> pGIT;
  107. HRESULT hr = NOERROR;
  108. VALIDATEPARM(hr, (pUnk == NULL || pdwCookie == NULL));
  109. if (FAILED(hr))
  110. return hr;
  111. TESTHR(hr, GetGIT(&pGIT));
  112. if (FAILED(hr))
  113. return hr;
  114. TESTHR(hr, pGIT->RegisterInterfaceInGlobal(pUnk, riid, pdwCookie));
  115. return hr;
  116. }
  117. // **************************************************************************
  118. HRESULT CPFComPtrThreadNeutral_GIT::RevokeInterface(DWORD dwCookie)
  119. {
  120. USE_TRACING("CPFComPtrThreadNeutral_GIT::RevokeInterface");
  121. CComPtr<IGlobalInterfaceTable> pGIT;
  122. HRESULT hr = NOERROR;
  123. TESTHR(hr, GetGIT(&pGIT));
  124. if (FAILED(hr))
  125. return hr;
  126. TESTHR(hr, pGIT->RevokeInterfaceFromGlobal(dwCookie));
  127. return hr;
  128. }
  129. // **************************************************************************
  130. HRESULT CPFComPtrThreadNeutral_GIT::GetInterface(DWORD dwCookie, REFIID riid,
  131. void **ppv)
  132. {
  133. USE_TRACING("CPFComPtrThreadNeutral_GIT::GetInterface");
  134. CComPtr<IGlobalInterfaceTable> pGIT;
  135. HRESULT hr;
  136. TESTHR(hr, GetGIT(&pGIT));
  137. if (FAILED(hr))
  138. return hr;
  139. TESTHR(hr, pGIT->GetInterfaceFromGlobal(dwCookie, riid, ppv));
  140. return hr;
  141. }
  142. /////////////////////////////////////////////////////////////////////////////
  143. // CPFCallItem
  144. // **************************************************************************
  145. CPFCallItem::CPFCallItem()
  146. {
  147. m_vt = VT_EMPTY; // VARTYPE m_vt;
  148. // CComPtrThreadNeutral<IUnknown> m_Unknown;
  149. // CComPtrThreadNeutral<IDispatch> m_Dispatch;
  150. // CComVariant m_Other;
  151. }
  152. // **************************************************************************
  153. CPFCallItem& CPFCallItem::operator=(const CComVariant& var)
  154. {
  155. switch(m_vt = var.vt)
  156. {
  157. case VT_UNKNOWN:
  158. m_Unknown = var.punkVal;
  159. break;
  160. case VT_DISPATCH:
  161. m_Dispatch = var.pdispVal;
  162. break;
  163. default:
  164. m_Other = var;
  165. break;
  166. }
  167. return *this;
  168. }
  169. // **************************************************************************
  170. CPFCallItem::operator CComVariant() const
  171. {
  172. CComVariant res;
  173. switch(m_vt)
  174. {
  175. case VT_UNKNOWN:
  176. res = (CComPtr<IUnknown>)m_Unknown;
  177. break;
  178. case VT_DISPATCH:
  179. res = (CComPtr<IDispatch>)m_Dispatch;
  180. break;
  181. default:
  182. res = m_Other;
  183. break;
  184. }
  185. return res;
  186. }
  187. /////////////////////////////////////////////////////////////////////////////
  188. // CPFCallDesc
  189. // **************************************************************************
  190. CPFCallDesc::CPFCallDesc(void)
  191. {
  192. m_rgciVars = NULL;
  193. m_dwVars = 0;
  194. }
  195. // **************************************************************************
  196. CPFCallDesc::~CPFCallDesc(void)
  197. {
  198. if (m_rgciVars != NULL)
  199. delete [] m_rgciVars;
  200. }
  201. // **************************************************************************
  202. HRESULT CPFCallDesc::Init(IDispatch *dispTarget, DISPID dispidMethod,
  203. const CComVariant *rgvVars, int dwVars)
  204. {
  205. USE_TRACING("CPFCallDesc::Init");
  206. HRESULT hr = NOERROR;
  207. m_rgciVars = new CPFCallItem[dwVars];
  208. VALIDATEEXPR(hr, (m_rgciVars == NULL), E_OUTOFMEMORY);
  209. if (FAILED(hr))
  210. return hr;
  211. m_dispTarget = dispTarget;
  212. m_dwVars = dwVars;
  213. m_dispidMethod = dispidMethod;
  214. if (m_rgciVars != NULL)
  215. {
  216. int i;
  217. for(i = 0; i < dwVars; i++)
  218. m_rgciVars[i] = rgvVars[i];
  219. }
  220. return hr;
  221. }
  222. // **************************************************************************
  223. HRESULT CPFCallDesc::Call(void)
  224. {
  225. USE_TRACING("CPFCallDesc::Call");
  226. CComPtr<IDispatch> dispTarget = m_dispTarget;
  227. CComVariant* pvars;
  228. CComVariant vResult;
  229. DISPPARAMS disp;
  230. HRESULT hr;
  231. DWORD i;
  232. VALIDATEEXPR(hr, (dispTarget == NULL), E_POINTER);
  233. if (FAILED(hr))
  234. return hr;
  235. pvars = new CComVariant[m_dwVars];
  236. VALIDATEEXPR(hr, (pvars == NULL), E_OUTOFMEMORY);
  237. if (FAILED(hr))
  238. return hr;
  239. for(i = 0; i < m_dwVars; i++)
  240. pvars[i] = m_rgciVars[i];
  241. ZeroMemory(&disp, sizeof(disp));
  242. disp.cArgs = m_dwVars;
  243. disp.rgvarg = pvars;
  244. TESTHR(hr, dispTarget->Invoke(m_dispidMethod, IID_NULL, LOCALE_USER_DEFAULT,
  245. DISPATCH_METHOD, &disp, &vResult, NULL, NULL));
  246. delete [] pvars;
  247. return hr;
  248. }
  249. /////////////////////////////////////////////////////////////////////////////
  250. // CPFModule
  251. // **************************************************************************
  252. HRESULT CPFModule::Init(void)
  253. {
  254. USE_TRACING("CPFModule::Init");
  255. HRESULT hr = NULL;
  256. TESTHR(hr, m_GITHolder.Init());
  257. return hr;
  258. }
  259. // **************************************************************************
  260. HRESULT CPFModule::Term(void)
  261. {
  262. USE_TRACING("CPFModule::Init");
  263. HRESULT hr = NULL;
  264. TESTHR(hr, m_GITHolder.Term());
  265. return hr;
  266. }