// // lbaddin.cpp // #include "private.h" #include "globals.h" #include "ctflbui.h" #include "regsvr.h" #include "cregkey.h" #include "tim.h" #include "lbaddin.h" const TCHAR c_szLangBarAddInKey[] = TEXT("SOFTWARE\\Microsoft\\CTF\\LangBarAddIn\\"); const TCHAR c_szGuid[] = TEXT("GUID"); const WCHAR c_wszFilePath[] = L"FilePath"; typedef HRESULT (STDAPICALLTYPE* LPFNCTFGETLANGBARADDIN)(ITfLangBarAddIn **ppAddIn); extern CPtrArray *g_rgSysThread; ////////////////////////////////////////////////////////////////////////////// // // LangBar AddIn service // ////////////////////////////////////////////////////////////////////////////// //+--------------------------------------------------------------------------- // // TF_RegisterLangBarAddIn // //+--------------------------------------------------------------------------- HRESULT TF_RegisterLangBarAddIn(REFGUID rguidUISrv, const WCHAR *pwszFile, DWORD dwFlags) { BOOL fLocalMachine = dwFlags & TF_RLBAI_LOCALMACHINE; if (IsEqualGUID(GUID_NULL, rguidUISrv)) return E_INVALIDARG; if (!pwszFile) return E_INVALIDARG; CMyRegKey key; TCHAR szKey[256]; StringCopyArray(szKey, c_szLangBarAddInKey); CLSIDToStringA(rguidUISrv, szKey + lstrlen(szKey)); if (key.Create(fLocalMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, szKey) != S_OK) return E_FAIL; if (key.SetValueW(pwszFile, c_wszFilePath) != S_OK) return E_FAIL; if (key.SetValue((dwFlags & TF_RLBAI_ENABLE) ? 1 : 0, c_szEnable) != S_OK) return E_FAIL; return S_OK; } //+--------------------------------------------------------------------------- // // TF_UnregisterLangBarAddIn // //+--------------------------------------------------------------------------- HRESULT TF_UnregisterLangBarAddIn(REFGUID rguidUISrv, DWORD dwFlags) { CMyRegKey key; TCHAR szKey[256]; TCHAR szSubKey[256]; BOOL fLocalMachine = dwFlags & TF_RLBAI_LOCALMACHINE; if (IsEqualGUID(GUID_NULL, rguidUISrv)) return E_INVALIDARG; StringCopyArray(szKey, c_szLangBarAddInKey); if (key.Open(fLocalMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, szKey, KEY_ALL_ACCESS) != S_OK) return E_FAIL; CLSIDToStringA(rguidUISrv, szSubKey); key.RecurseDeleteKey(szSubKey); return S_OK; } //+--------------------------------------------------------------------------- // // TF_ClearLangBarAddIns // //+--------------------------------------------------------------------------- HRESULT TF_ClearLangBarAddIns(REFCLSID rclsid) { int i; CicEnterCriticalSection(g_csInDllMain); if (g_rgSysThread) { int nCnt = g_rgSysThread->Count(); for (i = 0; i < nCnt; i++) { SYSTHREAD *psfn = g_rgSysThread->Get(i); if (psfn) { ClearLangBarAddIns(psfn, rclsid); } } } CicLeaveCriticalSection(g_csInDllMain); return S_OK; } BOOL ClearLangBarAddIns(SYSTHREAD *psfn, REFCLSID rclsid) { int i; int nCnt; if (!psfn->prgLBAddIn) return TRUE; nCnt = psfn->prgLBAddIn->Count(); for (i = nCnt - 1; i >= 0; i--) { LANGBARADDIN *pAddIn = psfn->prgLBAddIn->Get(i); if (pAddIn) { if (pAddIn->_plbai) { if (IsEqualGUID(rclsid, CLSID_NULL) || IsEqualGUID(rclsid, pAddIn->_clsid)) { _try { if (pAddIn->_fStarted) pAddIn->_plbai->OnTerminate(); pAddIn->_plbai->Release(); } _except(1) { Assert(0); } } } delete pAddIn; } psfn->prgLBAddIn->Remove(i, 1); } if (!psfn->prgLBAddIn->Count()) UninitLangBarAddIns(psfn); return TRUE; } //+--------------------------------------------------------------------------- // // InitLangBarAddInArray // //+--------------------------------------------------------------------------- void InitLangBarAddInArray() { CMyRegKey key; DWORD dwIndex; char szKey[MAX_PATH]; SYSTHREAD *psfn = GetSYSTHREAD(); BOOL fLocalMachine = FALSE; if (!psfn) return; if (key.Open(HKEY_CURRENT_USER, c_szLangBarAddInKey, KEY_READ) != S_OK) { // // if there is no addin current user, try local machine. // goto StartInLocalmachine; } TryAgainInLocalMachine: dwIndex = 0; while (key.EnumKey(dwIndex, szKey, ARRAYSIZE(szKey)) == S_OK) { CMyRegKey subkey; GUID guid; WCHAR wszFilePath[MAX_PATH]; LANGBARADDIN **ppAddIn; if (subkey.Open(key, szKey, KEY_READ) != S_OK) goto Next; if (subkey.QueryValueCchW(wszFilePath, c_wszFilePath, ARRAYSIZE(wszFilePath)) != S_OK) goto Next; StringAToCLSID(szKey, &guid); if (psfn->prgLBAddIn) { int i; int nCnt = psfn->prgLBAddIn->Count(); for (i = 0; i < nCnt; i++) { LANGBARADDIN *pAddIn = psfn->prgLBAddIn->Get(i); if (pAddIn && IsEqualGUID(pAddIn->_guid, guid)) goto Next; } } else { psfn->prgLBAddIn = new CPtrArray; if (!psfn->prgLBAddIn) { return; } } // // if there is no reg entry for Enable, the default is enabled. // DWORD dwRet; BOOL fEnabled = FALSE; if (subkey.QueryValue(dwRet, c_szEnable) == S_OK) { if (dwRet) fEnabled = TRUE; } ppAddIn = psfn->prgLBAddIn->Append(1); if (!ppAddIn) goto Next; *ppAddIn = new LANGBARADDIN; if (!*ppAddIn) goto Next; (*ppAddIn)->_guid = guid; (*ppAddIn)->_fEnabled = fEnabled ? TRUE : FALSE; StringCopyArrayW((*ppAddIn)->_wszFilePath, wszFilePath); Next: dwIndex++; } key.Close(); if (!fLocalMachine) { StartInLocalmachine: fLocalMachine = TRUE; if (key.Open(HKEY_LOCAL_MACHINE, c_szLangBarAddInKey, KEY_READ) == S_OK) { // // it is time to try local machine. // goto TryAgainInLocalMachine; } } return; } //+--------------------------------------------------------------------------- // // LoadLangBarAddIns // //+--------------------------------------------------------------------------- BOOL LoadLangBarAddIns(SYSTHREAD *psfn) { int i; int nCnt; if (psfn->fLBAddInLoaded) return TRUE; psfn->fLBAddInLoaded = TRUE; if (!psfn->prgLBAddIn) { InitLangBarAddInArray(); if (!psfn->prgLBAddIn) return FALSE; } if (!psfn->prgLBAddIn) return TRUE; nCnt = psfn->prgLBAddIn->Count(); for (i = 0; i < nCnt; i++) { LANGBARADDIN *pAddIn = psfn->prgLBAddIn->Get(i); LPFNCTFGETLANGBARADDIN pfn; ITfLangBarAddIn *plbai; if (!pAddIn) continue; if (pAddIn->_plbai) continue; if (!pAddIn->_fEnabled) continue; if (!pAddIn->_hInst) { if (IsOnNT()) pAddIn->_hInst = LoadLibraryW(pAddIn->_wszFilePath); else pAddIn->_hInst = LoadLibrary(WtoA(pAddIn->_wszFilePath)); } pfn = (LPFNCTFGETLANGBARADDIN)GetProcAddress(pAddIn->_hInst, TEXT("CTFGetLangBarAddIn")); if (!pfn) continue; if (FAILED(pfn(&plbai))) continue; pAddIn->_plbai = plbai; } return psfn->prgLBAddIn->Count() ? TRUE : FALSE; } //+--------------------------------------------------------------------------- // // UpdateLangBarAddIns // //+--------------------------------------------------------------------------- void UpdateLangBarAddIns() { int i; int nCnt; DWORD dwFlags = 0; SYSTHREAD *psfn = GetSYSTHREAD(); if (!psfn) return; if (!LoadLangBarAddIns(psfn)) return; if (!psfn->prgLBAddIn) return; if (psfn->ptim && psfn->ptim->_GetFocusDocInputMgr()) dwFlags = 1; nCnt = psfn->prgLBAddIn->Count(); for (i = 0; i < nCnt; i++) { LANGBARADDIN *pAddIn = psfn->prgLBAddIn->Get(i); if (!pAddIn) continue; if (!pAddIn->_plbai) continue; if (!pAddIn->_fEnabled) continue; if (!pAddIn->_fStarted) { pAddIn->_fStarted = TRUE; HRESULT hr = E_FAIL; _try { hr = pAddIn->_plbai->OnStart(&pAddIn->_clsid); } _except(1) { Assert(0); } if (FAILED(hr)) { pAddIn->_plbai->Release(); pAddIn->_plbai = NULL; continue; } } _try { pAddIn->_plbai->OnUpdate(dwFlags); } _except(1) { Assert(0); } } } //+--------------------------------------------------------------------------- // // TerminateLangBarAddIns // //+--------------------------------------------------------------------------- void UninitLangBarAddIns(SYSTHREAD *psfn) { if (psfn->prgLBAddIn) { // Assert(!psfn->prgLBAddIn->Count()); delete psfn->prgLBAddIn; psfn->prgLBAddIn = NULL; } psfn->fLBAddInLoaded = FALSE; }