|
|
//
// ithdmshl.cpp
//
#include "private.h"
#include "globals.h"
#include "tim.h"
#include "immxutil.h"
#include "nuihkl.h"
#include "nuictrl.h"
#include "cicmutex.h"
#include "ithdmshl.h"
#include "marshal.h"
#include "mproxy.h"
#include "thdutil.h"
LRESULT MyMarshalInterface(REFIID riid, BOOL fSameThread, LPUNKNOWN punk); HRESULT MyUnmarshalInterface(LRESULT ref, REFIID riid, BOOL fSameThread, void **ppvObject);
#define SZTHREADMIEVENT __TEXT("CTF.ThreadMarshalInterfaceEvent.%08X.%08X.%08X")
#define SZTHREADMICEVENT __TEXT("CTF.ThreadMIConnectionEvent.%08X.%08X.%08X")
#define MITYPE_LANGBARITEMMGR 1
#define MITYPE_TMQI 2
extern CCicMutex g_mutexTMD;
// --------------------------------------------------------------------------
//
// GetTIMInterfaceFromTYPE
//
// --------------------------------------------------------------------------
HRESULT GetTIMInrterfaceFromTYPE(DWORD dwType, REFIID riid, void **ppv) { HRESULT hr = E_FAIL; CThreadInputMgr *ptim;
switch (dwType) { case MITYPE_LANGBARITEMMGR: hr = TF_CreateLangBarItemMgr((ITfLangBarItemMgr **)ppv); break;
case MITYPE_TMQI: if ((ptim = CThreadInputMgr::_GetThis()) == NULL) break;
hr = ptim->QueryInterface(riid, ppv); break; }
return hr; }
// --------------------------------------------------------------------------
//
// FindTmd
//
// --------------------------------------------------------------------------
int FindTmd() { int nId; BOOL fFound = FALSE;
if (g_mutexTMD.Enter()) { for (nId = 0; nId < NUM_TMD; nId++) { if (!(GetSharedMemory()->tmd[nId].m_fInUse)) { GetSharedMemory()->tmd[nId].m_fInUse = TRUE; fFound = TRUE; break; } } Assert(fFound); g_mutexTMD.Leave(); }
return fFound ? nId : -1; }
// --------------------------------------------------------------------------
//
// GetThreadMarshallInterface()
//
// --------------------------------------------------------------------------
HRESULT GetThreadMarshalInterface(DWORD dwThreadId, DWORD dwType, REFIID riid, IUnknown **ppunk) { DWORD dwCurThreadId = GetCurrentThreadId(); HRESULT hr = E_FAIL; int nId = -1; CCicEvent event; CCicEvent eventc; SYSTHREAD *psfn; ULONG ulMshlCnt; CThreadMarshalWnd tmw; BOOL fSendReceiveConnection = FALSE; CCicSecAttr sa;
*ppunk = NULL;
if ((psfn = GetSYSTHREAD()) == NULL) return E_FAIL;
CModalLoop modalloop(psfn);
ulMshlCnt = psfn->ulMshlCnt++;
if (!EnsureMarshalWnd()) return E_FAIL;
if (dwCurThreadId == dwThreadId) { return GetTIMInrterfaceFromTYPE(dwType, riid, (void **)ppunk); }
nId = FindTmd(); if (nId == -1) goto Exit;
wsprintf(GetSharedMemory()->tmd[nId].m_szName, SZTHREADMIEVENT, dwCurThreadId, nId, ulMshlCnt); wsprintf(GetSharedMemory()->tmd[nId].m_szNameConnection, SZTHREADMICEVENT, dwCurThreadId, nId, ulMshlCnt);
GetSharedMemory()->tmd[nId].m_iid = riid; GetSharedMemory()->tmd[nId].m_dwThreadId = dwThreadId; GetSharedMemory()->tmd[nId].m_dwSrcThreadId = dwCurThreadId; GetSharedMemory()->tmd[nId].m_dwType = dwType; GetSharedMemory()->tmd[nId].m_ref = E_FAIL;
tmw.Init(dwThreadId);
if (!event.Create(sa, GetSharedMemory()->tmd[nId].m_szName)) { hr = E_FAIL; goto Exit; }
if (!eventc.Create(sa, GetSharedMemory()->tmd[nId].m_szNameConnection)) { hr = E_FAIL; goto Exit; }
if (!tmw.PostMarshalThreadMessage(g_msgThreadMarshal, MP_MARSHALINTERFACE, (LPARAM)nId)) { GetSharedMemory()->tmd[nId].m_ref = E_FAIL; goto SkipWaiting; }
if (GetSharedMemory()->tmd[nId].m_fInUse) { CCicTimer timer(10000); DWORD dwWaitFlags = QS_DEFAULTWAITFLAG; while (!timer.IsTimerAtZero()) { if (!fSendReceiveConnection && timer.IsTimerPass(DEFAULTMARSHALCONNECTIONTIMEOUT)) { DWORD dwReason = eventc.EventCheck(); if (dwReason != WAIT_OBJECT_0) { hr = E_FAIL; break; } fSendReceiveConnection = TRUE; }
hr = modalloop.BlockFn(&event, dwThreadId, dwWaitFlags); if (hr == S_OK) goto SkipWaiting;
if (FAILED(hr)) break; }
TraceMsg(TF_GENERAL, "ThreadMarshal Time Out"); goto Exit; }
SkipWaiting: if (FAILED(GetSharedMemory()->tmd[nId].m_ref)) goto Exit;
hr = CicCoUnmarshalInterface(GetSharedMemory()->tmd[nId].m_iid, dwThreadId, GetSharedMemory()->tmd[nId].m_ulStubId, GetSharedMemory()->tmd[nId].m_dwStubTime, (void **)ppunk);
Exit: if (nId != -1) GetSharedMemory()->tmd[nId].m_fInUse = FALSE;
return hr; }
// --------------------------------------------------------------------------
//
// ThreadMarshallInterfaceHandler()
//
// --------------------------------------------------------------------------
HRESULT ThreadMarshalInterfaceHandler(int nId) { HRESULT hr; IUnknown *punk;
if ((nId < 0) || (nId >= NUM_TMD)) return E_FAIL;
CCicEvent eventc; if (eventc.Open(GetSharedMemory()->tmd[nId].m_szNameConnection)) eventc.Set();
EnsureMarshalWnd();
hr = GetTIMInrterfaceFromTYPE(GetSharedMemory()->tmd[nId].m_dwType, GetSharedMemory()->tmd[nId].m_iid, (void **)&punk); if (FAILED(hr)) goto Exit;
hr = CicCoMarshalInterface(GetSharedMemory()->tmd[nId].m_iid, punk, &GetSharedMemory()->tmd[nId].m_ulStubId, &GetSharedMemory()->tmd[nId].m_dwStubTime, GetSharedMemory()->tmd[nId].m_dwSrcThreadId);
GetSharedMemory()->tmd[nId].m_ref = hr;
punk->Release(); Exit: CCicEvent event; if (event.Open(GetSharedMemory()->tmd[nId].m_szName)) event.Set();
return hr; }
// --------------------------------------------------------------------------
//
// GetThreadUIManager
//
// --------------------------------------------------------------------------
HRESULT GetThreadUIManager(DWORD dwThreadId, ITfLangBarItemMgr **pplbi, DWORD *pdwThreadId) { if (!dwThreadId) dwThreadId = GetSharedMemory()->dwFocusThread;
if (pdwThreadId) *pdwThreadId = dwThreadId;
return GetThreadMarshalInterface(dwThreadId, MITYPE_LANGBARITEMMGR, IID_ITfLangBarItemMgr, (IUnknown **)pplbi); }
// --------------------------------------------------------------------------
//
// GetActivateInputProcessor
//
// --------------------------------------------------------------------------
HRESULT GetInputProcessorProfiles(DWORD dwThreadId, ITfInputProcessorProfiles **ppaip, DWORD *pdwThreadId) { if (!dwThreadId) dwThreadId = GetSharedMemory()->dwFocusThread;
if (pdwThreadId) *pdwThreadId = dwThreadId;
return GetThreadMarshalInterface(dwThreadId, MITYPE_TMQI, IID_ITfInputProcessorProfiles, (IUnknown **)ppaip); }
// --------------------------------------------------------------------------
//
// ThreadUnMarshallInterfaceErrorHandler()
//
// --------------------------------------------------------------------------
HRESULT ThreadUnMarshalInterfaceErrorHandler(int nId) { HRESULT hr; IUnknown *punk;
hr = CicCoUnmarshalInterface(GetSharedMemory()->tmd[nId].m_iid, GetSharedMemory()->tmd[nId].m_dwThreadId, GetSharedMemory()->tmd[nId].m_ulStubId, GetSharedMemory()->tmd[nId].m_dwStubTime, (void **)&punk); if (SUCCEEDED(hr)) punk->Release(); GetSharedMemory()->tmd[nId].m_fInUse = FALSE; return hr; }
|