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.

309 lines
8.7 KiB

  1. //
  2. // ithdmshl.cpp
  3. //
  4. #include "private.h"
  5. #include "globals.h"
  6. #include "tim.h"
  7. #include "immxutil.h"
  8. #include "nuihkl.h"
  9. #include "nuictrl.h"
  10. #include "cicmutex.h"
  11. #include "ithdmshl.h"
  12. #include "marshal.h"
  13. #include "mproxy.h"
  14. #include "thdutil.h"
  15. LRESULT MyMarshalInterface(REFIID riid, BOOL fSameThread, LPUNKNOWN punk);
  16. HRESULT MyUnmarshalInterface(LRESULT ref, REFIID riid, BOOL fSameThread, void **ppvObject);
  17. #define SZTHREADMIEVENT __TEXT("CTF.ThreadMarshalInterfaceEvent.%08X.%08X.%08X")
  18. #define SZTHREADMICEVENT __TEXT("CTF.ThreadMIConnectionEvent.%08X.%08X.%08X")
  19. #define MITYPE_LANGBARITEMMGR 1
  20. #define MITYPE_TMQI 2
  21. extern CCicMutex g_mutexTMD;
  22. // --------------------------------------------------------------------------
  23. //
  24. // GetTIMInterfaceFromTYPE
  25. //
  26. // --------------------------------------------------------------------------
  27. HRESULT GetTIMInrterfaceFromTYPE(DWORD dwType, REFIID riid, void **ppv)
  28. {
  29. HRESULT hr = E_FAIL;
  30. CThreadInputMgr *ptim;
  31. switch (dwType)
  32. {
  33. case MITYPE_LANGBARITEMMGR:
  34. hr = TF_CreateLangBarItemMgr((ITfLangBarItemMgr **)ppv);
  35. break;
  36. case MITYPE_TMQI:
  37. if ((ptim = CThreadInputMgr::_GetThis()) == NULL)
  38. break;
  39. hr = ptim->QueryInterface(riid, ppv);
  40. break;
  41. }
  42. return hr;
  43. }
  44. // --------------------------------------------------------------------------
  45. //
  46. // FindTmd
  47. //
  48. // --------------------------------------------------------------------------
  49. int FindTmd()
  50. {
  51. int nId;
  52. BOOL fFound = FALSE;
  53. if (g_mutexTMD.Enter())
  54. {
  55. for (nId = 0; nId < NUM_TMD; nId++)
  56. {
  57. if (!(GetSharedMemory()->tmd[nId].m_fInUse))
  58. {
  59. GetSharedMemory()->tmd[nId].m_fInUse = TRUE;
  60. fFound = TRUE;
  61. break;
  62. }
  63. }
  64. Assert(fFound);
  65. g_mutexTMD.Leave();
  66. }
  67. return fFound ? nId : -1;
  68. }
  69. // --------------------------------------------------------------------------
  70. //
  71. // GetThreadMarshallInterface()
  72. //
  73. // --------------------------------------------------------------------------
  74. HRESULT GetThreadMarshalInterface(DWORD dwThreadId, DWORD dwType, REFIID riid, IUnknown **ppunk)
  75. {
  76. DWORD dwCurThreadId = GetCurrentThreadId();
  77. HRESULT hr = E_FAIL;
  78. int nId = -1;
  79. CCicEvent event;
  80. CCicEvent eventc;
  81. SYSTHREAD *psfn;
  82. ULONG ulMshlCnt;
  83. CThreadMarshalWnd tmw;
  84. BOOL fSendReceiveConnection = FALSE;
  85. CCicSecAttr sa;
  86. *ppunk = NULL;
  87. if ((psfn = GetSYSTHREAD()) == NULL)
  88. return E_FAIL;
  89. CModalLoop modalloop(psfn);
  90. ulMshlCnt = psfn->ulMshlCnt++;
  91. if (!EnsureMarshalWnd())
  92. return E_FAIL;
  93. if (dwCurThreadId == dwThreadId)
  94. {
  95. return GetTIMInrterfaceFromTYPE(dwType, riid, (void **)ppunk);
  96. }
  97. nId = FindTmd();
  98. if (nId == -1)
  99. goto Exit;
  100. wsprintf(GetSharedMemory()->tmd[nId].m_szName, SZTHREADMIEVENT, dwCurThreadId, nId, ulMshlCnt);
  101. wsprintf(GetSharedMemory()->tmd[nId].m_szNameConnection, SZTHREADMICEVENT, dwCurThreadId, nId, ulMshlCnt);
  102. GetSharedMemory()->tmd[nId].m_iid = riid;
  103. GetSharedMemory()->tmd[nId].m_dwThreadId = dwThreadId;
  104. GetSharedMemory()->tmd[nId].m_dwSrcThreadId = dwCurThreadId;
  105. GetSharedMemory()->tmd[nId].m_dwType = dwType;
  106. GetSharedMemory()->tmd[nId].m_ref = E_FAIL;
  107. tmw.Init(dwThreadId);
  108. if (!event.Create(sa, GetSharedMemory()->tmd[nId].m_szName))
  109. {
  110. hr = E_FAIL;
  111. goto Exit;
  112. }
  113. if (!eventc.Create(sa, GetSharedMemory()->tmd[nId].m_szNameConnection))
  114. {
  115. hr = E_FAIL;
  116. goto Exit;
  117. }
  118. if (!tmw.PostMarshalThreadMessage(g_msgThreadMarshal,
  119. MP_MARSHALINTERFACE,
  120. (LPARAM)nId))
  121. {
  122. GetSharedMemory()->tmd[nId].m_ref = E_FAIL;
  123. goto SkipWaiting;
  124. }
  125. if (GetSharedMemory()->tmd[nId].m_fInUse)
  126. {
  127. CCicTimer timer(10000);
  128. DWORD dwWaitFlags = QS_DEFAULTWAITFLAG;
  129. while (!timer.IsTimerAtZero())
  130. {
  131. if (!fSendReceiveConnection &&
  132. timer.IsTimerPass(DEFAULTMARSHALCONNECTIONTIMEOUT))
  133. {
  134. DWORD dwReason = eventc.EventCheck();
  135. if (dwReason != WAIT_OBJECT_0)
  136. {
  137. hr = E_FAIL;
  138. break;
  139. }
  140. fSendReceiveConnection = TRUE;
  141. }
  142. hr = modalloop.BlockFn(&event, dwThreadId, dwWaitFlags);
  143. if (hr == S_OK)
  144. goto SkipWaiting;
  145. if (FAILED(hr))
  146. break;
  147. }
  148. TraceMsg(TF_GENERAL, "ThreadMarshal Time Out");
  149. goto Exit;
  150. }
  151. SkipWaiting:
  152. if (FAILED(GetSharedMemory()->tmd[nId].m_ref))
  153. goto Exit;
  154. hr = CicCoUnmarshalInterface(GetSharedMemory()->tmd[nId].m_iid,
  155. dwThreadId,
  156. GetSharedMemory()->tmd[nId].m_ulStubId,
  157. GetSharedMemory()->tmd[nId].m_dwStubTime,
  158. (void **)ppunk);
  159. Exit:
  160. if (nId != -1)
  161. GetSharedMemory()->tmd[nId].m_fInUse = FALSE;
  162. return hr;
  163. }
  164. // --------------------------------------------------------------------------
  165. //
  166. // ThreadMarshallInterfaceHandler()
  167. //
  168. // --------------------------------------------------------------------------
  169. HRESULT ThreadMarshalInterfaceHandler(int nId)
  170. {
  171. HRESULT hr;
  172. IUnknown *punk;
  173. if ((nId < 0) || (nId >= NUM_TMD))
  174. return E_FAIL;
  175. CCicEvent eventc;
  176. if (eventc.Open(GetSharedMemory()->tmd[nId].m_szNameConnection))
  177. eventc.Set();
  178. EnsureMarshalWnd();
  179. hr = GetTIMInrterfaceFromTYPE(GetSharedMemory()->tmd[nId].m_dwType,
  180. GetSharedMemory()->tmd[nId].m_iid, (void **)&punk);
  181. if (FAILED(hr))
  182. goto Exit;
  183. hr = CicCoMarshalInterface(GetSharedMemory()->tmd[nId].m_iid,
  184. punk,
  185. &GetSharedMemory()->tmd[nId].m_ulStubId,
  186. &GetSharedMemory()->tmd[nId].m_dwStubTime,
  187. GetSharedMemory()->tmd[nId].m_dwSrcThreadId);
  188. GetSharedMemory()->tmd[nId].m_ref = hr;
  189. punk->Release();
  190. Exit:
  191. CCicEvent event;
  192. if (event.Open(GetSharedMemory()->tmd[nId].m_szName))
  193. event.Set();
  194. return hr;
  195. }
  196. // --------------------------------------------------------------------------
  197. //
  198. // GetThreadUIManager
  199. //
  200. // --------------------------------------------------------------------------
  201. HRESULT GetThreadUIManager(DWORD dwThreadId, ITfLangBarItemMgr **pplbi, DWORD *pdwThreadId)
  202. {
  203. if (!dwThreadId)
  204. dwThreadId = GetSharedMemory()->dwFocusThread;
  205. if (pdwThreadId)
  206. *pdwThreadId = dwThreadId;
  207. return GetThreadMarshalInterface(dwThreadId,
  208. MITYPE_LANGBARITEMMGR,
  209. IID_ITfLangBarItemMgr,
  210. (IUnknown **)pplbi);
  211. }
  212. // --------------------------------------------------------------------------
  213. //
  214. // GetActivateInputProcessor
  215. //
  216. // --------------------------------------------------------------------------
  217. HRESULT GetInputProcessorProfiles(DWORD dwThreadId, ITfInputProcessorProfiles **ppaip, DWORD *pdwThreadId)
  218. {
  219. if (!dwThreadId)
  220. dwThreadId = GetSharedMemory()->dwFocusThread;
  221. if (pdwThreadId)
  222. *pdwThreadId = dwThreadId;
  223. return GetThreadMarshalInterface(dwThreadId,
  224. MITYPE_TMQI,
  225. IID_ITfInputProcessorProfiles,
  226. (IUnknown **)ppaip);
  227. }
  228. // --------------------------------------------------------------------------
  229. //
  230. // ThreadUnMarshallInterfaceErrorHandler()
  231. //
  232. // --------------------------------------------------------------------------
  233. HRESULT ThreadUnMarshalInterfaceErrorHandler(int nId)
  234. {
  235. HRESULT hr;
  236. IUnknown *punk;
  237. hr = CicCoUnmarshalInterface(GetSharedMemory()->tmd[nId].m_iid,
  238. GetSharedMemory()->tmd[nId].m_dwThreadId,
  239. GetSharedMemory()->tmd[nId].m_ulStubId,
  240. GetSharedMemory()->tmd[nId].m_dwStubTime,
  241. (void **)&punk);
  242. if (SUCCEEDED(hr))
  243. punk->Release();
  244. GetSharedMemory()->tmd[nId].m_fInUse = FALSE;
  245. return hr;
  246. }