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.

1870 lines
49 KiB

  1. /*++
  2. Copyright (c) 2001, Microsoft Corporation
  3. Module Name:
  4. com.c
  5. Abstract:
  6. This file implements the COM entry.
  7. Author:
  8. Revision History:
  9. Notes:
  10. --*/
  11. #include "precomp.h"
  12. #define COBJMACROS
  13. #include "msctf.h"
  14. #include "tlapi.h"
  15. #include "apcompat.h"
  16. #ifdef CUAS_ENABLE
  17. #ifndef RtlIsThreadWithinLoaderCallout
  18. BOOLEAN NTAPI RtlIsThreadWithinLoaderCallout (VOID);
  19. #endif
  20. HRESULT CtfAImmCreateInputContext(HIMC himc);
  21. HRESULT ActivateOrDeactivateTIM( BOOL fActivate);
  22. DWORD GetCoInitCountSkip();
  23. DWORD IncCoInitCountSkip();
  24. DWORD DecCoInitCountSkip();
  25. HRESULT Internal_CoInitializeEx(void* pv, DWORD dw);
  26. //+---------------------------------------------------------------------------
  27. //
  28. // For InitializeSpy
  29. //
  30. //----------------------------------------------------------------------------
  31. typedef struct _IMMISPY
  32. {
  33. IInitializeSpy;
  34. ULONG cref;
  35. } IMMISPY;
  36. //+---------------------------------------------------------------------------
  37. //
  38. // CTFIMMTLS
  39. //
  40. //----------------------------------------------------------------------------
  41. typedef struct _CTFIMMTLS
  42. {
  43. IMMISPY *pimmispy;
  44. ULARGE_INTEGER uliISpyCookie;
  45. DWORD dwInRefCountSkipMode;
  46. DWORD dwRefCountSkip;
  47. BOOL fInCtfImmCoUninitialize;
  48. } CTFIMMTLS;
  49. CTFIMMTLS* GetTLS();
  50. IMMISPY *AllocIMMISPY();
  51. void DeleteIMMISPY(IMMISPY *pimmispy);
  52. //+---------------------------------------------------------------------------
  53. //
  54. // _InsideLoaderLock()
  55. //
  56. //----------------------------------------------------------------------------
  57. BOOL _InsideLoaderLock()
  58. {
  59. return (NtCurrentTeb()->ClientId.UniqueThread ==
  60. ((PRTL_CRITICAL_SECTION)(NtCurrentPeb()->LoaderLock))->OwningThread);
  61. }
  62. //+---------------------------------------------------------------------------
  63. //
  64. // PImmISpyFromPISpy
  65. //
  66. //----------------------------------------------------------------------------
  67. IMMISPY *PImmISpyFromPISpy(IInitializeSpy *pispy)
  68. {
  69. return (IMMISPY *)pispy;
  70. }
  71. //+---------------------------------------------------------------------------
  72. //
  73. // ISPY_AddRef
  74. //
  75. //----------------------------------------------------------------------------
  76. ULONG ISPY_AddRef(IInitializeSpy *pispy)
  77. {
  78. IMMISPY *pimmispy = PImmISpyFromPISpy(pispy);
  79. pimmispy->cref++;
  80. return pimmispy->cref;
  81. }
  82. //+---------------------------------------------------------------------------
  83. //
  84. // ISPY_Release
  85. //
  86. //----------------------------------------------------------------------------
  87. ULONG ISPY_Release(IInitializeSpy *pispy)
  88. {
  89. IMMISPY *pimmispy = PImmISpyFromPISpy(pispy);
  90. pimmispy->cref--;
  91. if (!pimmispy->cref)
  92. {
  93. DeleteIMMISPY(pimmispy);
  94. return 0;
  95. }
  96. return pimmispy->cref;
  97. }
  98. //+---------------------------------------------------------------------------
  99. //
  100. // ISPY_QueryInterface
  101. //
  102. //----------------------------------------------------------------------------
  103. HRESULT ISPY_QueryInterface(IInitializeSpy *pispy,
  104. REFIID riid,
  105. void **ppvObject)
  106. {
  107. if (!ppvObject)
  108. return E_INVALIDARG;
  109. *ppvObject = NULL;
  110. if (IsEqualIID(riid, &IID_IUnknown) ||
  111. IsEqualIID(riid, &IID_IInitializeSpy))
  112. {
  113. ISPY_AddRef(pispy);
  114. *ppvObject = pispy;
  115. return S_OK;
  116. }
  117. return E_NOINTERFACE;
  118. }
  119. //+---------------------------------------------------------------------------
  120. //
  121. // ISPY_PreInitialize
  122. //
  123. //----------------------------------------------------------------------------
  124. HRESULT ISPY_PreInitialize(IInitializeSpy * pispy,
  125. DWORD dwCoInit,
  126. DWORD dwCurThreadAptRefs)
  127. {
  128. DWORD dwRet = IncCoInitCountSkip();
  129. UNREFERENCED_PARAMETER(pispy);
  130. //
  131. // If we already initialize com and a 2nd initialization is MT,
  132. // we should disable CUAS. So the CoInit(MT) from caller will work.
  133. //
  134. if (GetClientInfo()->CI_flags & CI_CUAS_COINIT_CALLED)
  135. {
  136. if ((dwCurThreadAptRefs == (dwRet + 1)) &&
  137. (dwCoInit == COINIT_MULTITHREADED))
  138. {
  139. ActivateOrDeactivateTIM(FALSE);
  140. CtfImmCoUninitialize();
  141. }
  142. }
  143. return S_OK;
  144. }
  145. //+---------------------------------------------------------------------------
  146. //
  147. // ISPY_PostInitialize
  148. //
  149. //----------------------------------------------------------------------------
  150. HRESULT ISPY_PostInitialize(IInitializeSpy * pispy,
  151. HRESULT hrCoInit,
  152. DWORD dwCoInit,
  153. DWORD dwNewThreadAptRefs)
  154. {
  155. DWORD dwRet = GetCoInitCountSkip();
  156. UNREFERENCED_PARAMETER(pispy);
  157. UNREFERENCED_PARAMETER(dwCoInit);
  158. //
  159. // If we already initialize com and got a 2nd initialization,
  160. // change the return value to S_OK. So the caller think
  161. // that it is the first initialization.
  162. //
  163. if (GetClientInfo()->CI_flags & CI_CUAS_COINIT_CALLED)
  164. {
  165. if ((hrCoInit == S_FALSE) && (dwNewThreadAptRefs == (dwRet + 2)))
  166. {
  167. return S_OK;
  168. }
  169. }
  170. return hrCoInit;
  171. }
  172. //+---------------------------------------------------------------------------
  173. //
  174. // ISPY_PreUninitialize
  175. //
  176. //----------------------------------------------------------------------------
  177. HRESULT ISPY_PreUninitialize(IInitializeSpy * pispy,
  178. DWORD dwCurThreadAptRefs)
  179. {
  180. UNREFERENCED_PARAMETER(pispy);
  181. UNREFERENCED_PARAMETER(dwCurThreadAptRefs);
  182. //
  183. // #607467
  184. //
  185. // Norton Systemworks setup calls CoUninitialize() without calling
  186. // CoInitialize(). So we got under ref problem.
  187. // If the last ref count is ours, we recover it by calling
  188. // CoInitializeEx().
  189. //
  190. if (dwCurThreadAptRefs == 1)
  191. {
  192. if (!RtlDllShutdownInProgress() &&
  193. !_InsideLoaderLock() &&
  194. (GetClientInfo()->CI_flags & CI_CUAS_COINIT_CALLED))
  195. {
  196. CTFIMMTLS* ptls = GetTLS();
  197. if (ptls && !ptls->fInCtfImmCoUninitialize)
  198. {
  199. Internal_CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  200. }
  201. }
  202. }
  203. return S_OK;
  204. }
  205. //+---------------------------------------------------------------------------
  206. //
  207. // ISPY_PostUninitialize
  208. //
  209. //----------------------------------------------------------------------------
  210. HRESULT ISPY_PostUninitialize(IInitializeSpy * pispy,
  211. DWORD dwNewThreadAptRefs)
  212. {
  213. UNREFERENCED_PARAMETER(pispy);
  214. UNREFERENCED_PARAMETER(dwNewThreadAptRefs);
  215. DecCoInitCountSkip();
  216. return S_OK;
  217. }
  218. //+---------------------------------------------------------------------------
  219. //
  220. // g_vtbnlISPY
  221. //
  222. //----------------------------------------------------------------------------
  223. IInitializeSpyVtbl g_vtblISPY = {
  224. ISPY_QueryInterface,
  225. ISPY_AddRef,
  226. ISPY_Release,
  227. ISPY_PreInitialize,
  228. ISPY_PostInitialize,
  229. ISPY_PreUninitialize,
  230. ISPY_PostUninitialize,
  231. };
  232. //+---------------------------------------------------------------------------
  233. //
  234. // AllocIMMISPY
  235. //
  236. //----------------------------------------------------------------------------
  237. IMMISPY *AllocIMMISPY()
  238. {
  239. IMMISPY *pimmispy = ImmLocalAlloc(0, sizeof(IMMISPY));
  240. if (!pimmispy)
  241. return NULL;
  242. pimmispy->lpVtbl = &g_vtblISPY;
  243. pimmispy->cref = 1;
  244. return pimmispy;
  245. }
  246. //+---------------------------------------------------------------------------
  247. //
  248. // DeletIMMISPY
  249. //
  250. //----------------------------------------------------------------------------
  251. void DeleteIMMISPY(IMMISPY *pimmispy)
  252. {
  253. ImmLocalFree(pimmispy);
  254. }
  255. //////////////////////////////////////////////////////////////////////////////
  256. //
  257. // TLS
  258. //
  259. //////////////////////////////////////////////////////////////////////////////
  260. DWORD g_dwTLSIndex = (DWORD)-1;
  261. //+---------------------------------------------------------------------------
  262. //
  263. // InitTLS
  264. //
  265. //----------------------------------------------------------------------------
  266. void InitTLS()
  267. {
  268. RtlEnterCriticalSection(&gcsImeDpi);
  269. if (g_dwTLSIndex == (DWORD)-1)
  270. g_dwTLSIndex = TlsAlloc();
  271. RtlLeaveCriticalSection(&gcsImeDpi);
  272. }
  273. //+---------------------------------------------------------------------------
  274. //
  275. // InternalAllocateTLS
  276. //
  277. //----------------------------------------------------------------------------
  278. CTFIMMTLS* InternalAllocateTLS()
  279. {
  280. CTFIMMTLS* ptls;
  281. if (g_dwTLSIndex == (DWORD)-1)
  282. return NULL;
  283. ptls = (CTFIMMTLS*)TlsGetValue(g_dwTLSIndex);
  284. if (ptls == NULL)
  285. {
  286. if ((ptls = (CTFIMMTLS*)ImmLocalAlloc(HEAP_ZERO_MEMORY,
  287. sizeof(CTFIMMTLS))) == NULL)
  288. return NULL;
  289. if (!TlsSetValue(g_dwTLSIndex, ptls))
  290. {
  291. ImmLocalFree(ptls);
  292. return NULL;
  293. }
  294. }
  295. return ptls;
  296. }
  297. //+---------------------------------------------------------------------------
  298. //
  299. // GetTLS
  300. //
  301. //----------------------------------------------------------------------------
  302. CTFIMMTLS* GetTLS()
  303. {
  304. if (g_dwTLSIndex == (DWORD)-1)
  305. return NULL;
  306. return (CTFIMMTLS*)TlsGetValue(g_dwTLSIndex);
  307. }
  308. //+---------------------------------------------------------------------------
  309. //
  310. // CtfImmEnterCoInitCountSkipMode
  311. //
  312. //----------------------------------------------------------------------------
  313. BOOL WINAPI CtfImmEnterCoInitCountSkipMode()
  314. {
  315. CTFIMMTLS* ptls = GetTLS();
  316. if (!ptls)
  317. return FALSE;
  318. ptls->dwInRefCountSkipMode++;
  319. return TRUE;
  320. }
  321. //+---------------------------------------------------------------------------
  322. //
  323. // CtfImmLeaveCoInitCountSkip
  324. //
  325. //----------------------------------------------------------------------------
  326. BOOL WINAPI CtfImmLeaveCoInitCountSkipMode()
  327. {
  328. CTFIMMTLS* ptls = GetTLS();
  329. if (!ptls)
  330. return FALSE;
  331. if (ptls->dwInRefCountSkipMode < 1)
  332. {
  333. UserAssert(0);
  334. return FALSE;
  335. }
  336. ptls->dwInRefCountSkipMode--;
  337. return TRUE;
  338. }
  339. //+---------------------------------------------------------------------------
  340. //
  341. // GetCoInitCountSkip
  342. //
  343. //----------------------------------------------------------------------------
  344. DWORD GetCoInitCountSkip()
  345. {
  346. CTFIMMTLS* ptls = GetTLS();
  347. if (!ptls)
  348. return 0;
  349. return ptls->dwRefCountSkip;
  350. }
  351. //+---------------------------------------------------------------------------
  352. //
  353. // IncCoInitCountSkip
  354. //
  355. //----------------------------------------------------------------------------
  356. DWORD IncCoInitCountSkip()
  357. {
  358. DWORD dwRet = 0;
  359. CTFIMMTLS* ptls = GetTLS();
  360. if (!ptls)
  361. return dwRet;
  362. dwRet = ptls->dwRefCountSkip;
  363. if (ptls->dwInRefCountSkipMode)
  364. ptls->dwRefCountSkip++;
  365. return dwRet;
  366. }
  367. //+---------------------------------------------------------------------------
  368. //
  369. // DecCoInitCountSkip
  370. //
  371. //----------------------------------------------------------------------------
  372. DWORD DecCoInitCountSkip()
  373. {
  374. DWORD dwRet = 0;
  375. CTFIMMTLS* ptls = GetTLS();
  376. if (!ptls)
  377. return dwRet;
  378. dwRet = ptls->dwRefCountSkip;
  379. if (ptls->dwInRefCountSkipMode)
  380. {
  381. if (ptls->dwRefCountSkip < 1)
  382. {
  383. UserAssert(0);
  384. return dwRet;
  385. }
  386. ptls->dwRefCountSkip--;
  387. }
  388. return dwRet;
  389. }
  390. //+---------------------------------------------------------------------------
  391. //
  392. // InternalDestroyTLS
  393. //
  394. //----------------------------------------------------------------------------
  395. BOOL InternalDestroyTLS()
  396. {
  397. CTFIMMTLS* ptls;
  398. ptls = (CTFIMMTLS*)TlsGetValue(g_dwTLSIndex);
  399. if (ptls != NULL)
  400. {
  401. ImmLocalFree(ptls);
  402. TlsSetValue(g_dwTLSIndex, NULL);
  403. return TRUE;
  404. }
  405. return FALSE;
  406. }
  407. /*
  408. * Text frame service processing is disabled for all the thread in the current process
  409. */
  410. BOOL g_disable_CUAS_flag = FALSE;
  411. //+---------------------------------------------------------------------------
  412. //
  413. // delay load
  414. //
  415. //----------------------------------------------------------------------------
  416. FARPROC GetFn(HINSTANCE *phInst, TCHAR *pchLib, char *pchFunc)
  417. {
  418. if (*phInst == NULL)
  419. {
  420. *phInst = LoadLibrary(pchLib);
  421. if (*phInst == NULL)
  422. {
  423. UserAssert(0);
  424. return NULL;
  425. }
  426. }
  427. return GetProcAddress(*phInst, pchFunc);
  428. }
  429. HINSTANCE g_hOle32 = NULL;
  430. HRESULT Internal_CoInitializeEx(void* pv, DWORD dw)
  431. {
  432. static FARPROC pfn = NULL;
  433. if (pfn == NULL || g_hOle32 == NULL) {
  434. pfn = GetFn(&g_hOle32, L"ole32.dll", "CoInitializeEx");
  435. if (pfn == NULL) {
  436. UserAssert(0);
  437. return E_FAIL;
  438. }
  439. }
  440. return (HRESULT)(*pfn)(pv, dw);
  441. }
  442. void Internal_CoUninitialize()
  443. {
  444. static FARPROC pfn = NULL;
  445. if (pfn == NULL || g_hOle32 == NULL) {
  446. pfn = GetFn(&g_hOle32, L"ole32.dll", "CoUninitialize");
  447. if (pfn == NULL) {
  448. UserAssert(0);
  449. return;
  450. }
  451. }
  452. (*pfn)();
  453. }
  454. HRESULT Internal_CoRegisterInitializeSpy(LPINITIALIZESPY pSpy,
  455. ULARGE_INTEGER *puliCookie)
  456. {
  457. static FARPROC pfn = NULL;
  458. if (pfn == NULL || g_hOle32 == NULL) {
  459. pfn = GetFn(&g_hOle32, L"ole32.dll", "CoRegisterInitializeSpy");
  460. if (pfn == NULL) {
  461. UserAssert(0);
  462. return E_FAIL;
  463. }
  464. }
  465. return (HRESULT)(*pfn)(pSpy, puliCookie);
  466. }
  467. HRESULT Internal_CoRevokeInitializeSpy(ULARGE_INTEGER uliCookie)
  468. {
  469. static FARPROC pfn = NULL;
  470. if (pfn == NULL || g_hOle32 == NULL) {
  471. pfn = GetFn(&g_hOle32, L"ole32.dll", "CoRevokeInitializeSpy");
  472. if (pfn == NULL) {
  473. UserAssert(0);
  474. return E_FAIL;
  475. }
  476. }
  477. return (HRESULT)(*pfn)(uliCookie);
  478. }
  479. HINSTANCE g_hMsctf = NULL;
  480. HRESULT Internal_TF_CreateLangBarMgr(ITfLangBarMgr** pv)
  481. {
  482. static FARPROC pfn = NULL;
  483. if (pfn == NULL || g_hMsctf == NULL) {
  484. pfn = GetFn(&g_hMsctf, L"msctf.dll", "TF_CreateLangBarMgr");
  485. if (pfn == NULL) {
  486. UserAssert(0);
  487. return E_FAIL;
  488. }
  489. }
  490. return (HRESULT)(*pfn)(pv);
  491. }
  492. DWORD Internal_TF_CicNotify(int nCode, WPARAM wParam, LPARAM lParam)
  493. {
  494. static FARPROC pfn = NULL;
  495. if (pfn == NULL || g_hMsctf == NULL) {
  496. pfn = GetFn(&g_hMsctf, L"msctf.dll", "TF_CicNotify");
  497. if (pfn == NULL) {
  498. UserAssert(0);
  499. return E_FAIL;
  500. }
  501. }
  502. return (DWORD)(*pfn)(nCode, wParam, lParam);
  503. }
  504. #if 0
  505. HINSTANCE g_hNtdll = NULL;
  506. BOOLEAN Internal_RtlIsThreadWithinLoaderCallout(VOID)
  507. {
  508. static FARPROC pfn = NULL;
  509. if (pfn == NULL || g_hNtdll == NULL) {
  510. pfn = GetFn(&g_hNtdll, L"ntdll.dll", "RtlIsThreadWithinLoaderCallout");
  511. if (pfn == NULL) {
  512. UserAssert(0);
  513. return FALSE;
  514. }
  515. }
  516. return (BOOLEAN)(*pfn)();
  517. }
  518. #endif
  519. //+---------------------------------------------------------------------------
  520. //
  521. // CtfImmCoInitialize
  522. //
  523. //----------------------------------------------------------------------------
  524. HRESULT
  525. CtfImmCoInitialize()
  526. {
  527. //
  528. // CoInitializeEx
  529. //
  530. HRESULT hr = E_NOINTERFACE;
  531. //
  532. // Check CI flag
  533. //
  534. if (GetClientInfo()->CI_flags & CI_CUAS_COINIT_CALLED)
  535. return S_OK;
  536. hr = Internal_CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
  537. if (SUCCEEDED(hr))
  538. {
  539. RIPMSG0(RIP_VERBOSE, "CtfImmCoInitialize succeeded.");
  540. //
  541. // Set CI flag
  542. //
  543. GetClientInfo()->CI_flags |= CI_CUAS_COINIT_CALLED;
  544. {
  545. CTFIMMTLS* ptls;
  546. //
  547. // Initialize CoInitSpy.
  548. //
  549. InitTLS();
  550. ptls = InternalAllocateTLS();
  551. if (ptls && !ptls->pimmispy)
  552. {
  553. ptls->pimmispy = AllocIMMISPY();
  554. if (ptls->pimmispy)
  555. {
  556. HRESULT hrTemp;
  557. hrTemp = Internal_CoRegisterInitializeSpy((LPINITIALIZESPY)ptls->pimmispy,
  558. &(ptls->uliISpyCookie));
  559. if (FAILED(hrTemp))
  560. {
  561. DeleteIMMISPY(ptls->pimmispy);
  562. ptls->pimmispy = NULL;
  563. memset(&ptls->uliISpyCookie, 0, sizeof(ULARGE_INTEGER));
  564. }
  565. }
  566. }
  567. }
  568. hr = S_OK;
  569. }
  570. else
  571. {
  572. RIPMSG1(RIP_WARNING, "CtfImmCoInitialize failed. err=%x", hr);
  573. }
  574. return hr;
  575. }
  576. //+---------------------------------------------------------------------------
  577. //
  578. // CtfImmCoUninitialize
  579. //
  580. //----------------------------------------------------------------------------
  581. void WINAPI
  582. CtfImmCoUninitialize()
  583. {
  584. if (GetClientInfo()->CI_flags & CI_CUAS_COINIT_CALLED)
  585. {
  586. CTFIMMTLS* ptls = GetTLS();
  587. if (ptls)
  588. {
  589. ptls->fInCtfImmCoUninitialize = TRUE;
  590. Internal_CoUninitialize();
  591. ptls->fInCtfImmCoUninitialize = FALSE;
  592. GetClientInfo()->CI_flags &= ~CI_CUAS_COINIT_CALLED;
  593. }
  594. {
  595. CTFIMMTLS* ptls;
  596. //
  597. // revoke initialize spy
  598. //
  599. ptls = InternalAllocateTLS();
  600. if (ptls && ptls->pimmispy)
  601. {
  602. Internal_CoRevokeInitializeSpy(ptls->uliISpyCookie);
  603. ISPY_Release((IInitializeSpy *)ptls->pimmispy);
  604. ptls->pimmispy = NULL;
  605. memset(&ptls->uliISpyCookie, 0, sizeof(ULARGE_INTEGER));
  606. }
  607. }
  608. }
  609. }
  610. //+---------------------------------------------------------------------------
  611. //
  612. // CtfImmTIMActivate
  613. //
  614. //----------------------------------------------------------------------------
  615. HRESULT
  616. CtfImmTIMActivate(
  617. HKL hKL)
  618. {
  619. HRESULT hr = S_OK;
  620. /*
  621. * Text frame service processing is disabled for all the thread in the current process
  622. */
  623. if (g_disable_CUAS_flag) {
  624. RIPMSG0(RIP_VERBOSE, "CtfImmTIMActivate: g_disable_CUAS_flag is ON.");
  625. /*
  626. * set client info flag.
  627. */
  628. GetClientInfo()->CI_flags |= CI_CUAS_DISABLE;
  629. return hr;
  630. }
  631. /*
  632. * Check client info flag.
  633. */
  634. if (GetClientInfo()->CI_flags & CI_CUAS_DISABLE) {
  635. RIPMSG0(RIP_VERBOSE, "CtfImmTIMActivate: CI_CUAS_DISABLE is ON.");
  636. return hr;
  637. }
  638. /*
  639. * Check Disable Advanced Text Services switch.
  640. * If it is On, doesn't activate TIM.
  641. */
  642. if (IsDisabledTextServices()) {
  643. /*
  644. * set client info flag.
  645. */
  646. GetClientInfo()->CI_flags |= CI_CUAS_DISABLE;
  647. RIPMSG0(RIP_VERBOSE, "CtfImmTIMActivate: Disabled Text Services.");
  648. return hr;
  649. }
  650. /*
  651. * Check a interactive user logon.
  652. */
  653. if (!IsInteractiveUserLogon() || IsRunningInMsoobe()) {
  654. RIPMSG0(RIP_VERBOSE, "CtfImmTIMActivate: Not a interactive user logon. or MSOOBE mode");
  655. return hr;
  656. }
  657. /*
  658. * Check CUAS switch. If CUAS is OFF, doesn't activate TIM.
  659. */
  660. if (! IsCUASEnabled()) {
  661. /*
  662. * If AIMM enabled, then return S_OK;
  663. */
  664. DWORD dwImeCompatFlags = ImmGetAppCompatFlags(NULL);
  665. if (dwImeCompatFlags & (IMECOMPAT_AIMM12 | IMECOMPAT_AIMM_LEGACY_CLSID | IMECOMPAT_AIMM12_TRIDENT)) {
  666. return S_OK;
  667. }
  668. /*
  669. * set client info flag.
  670. */
  671. GetClientInfo()->CI_flags |= CI_CUAS_DISABLE;
  672. RIPMSG0(RIP_VERBOSE, "CtfImmTIMActivate: CUAS switch is OFF.");
  673. return hr;
  674. }
  675. /*
  676. *
  677. * KACF_DISABLECICERO is already defined in private/Lab06_DEV
  678. * we will use this flag later.
  679. *
  680. * APPCOMPATFLAG(KACF_DISABLECICERO)
  681. * KACF_DISABLECICERO is 0x100
  682. */
  683. #ifndef KACF_DISABLECICERO
  684. #define KACF_DISABLECICERO 0x00000100 // If set. Cicero support for the current process
  685. // is disabled.
  686. #endif
  687. if (APPCOMPATFLAG(KACF_DISABLECICERO)) {
  688. /*
  689. * set client info flag.
  690. */
  691. GetClientInfo()->CI_flags |= CI_CUAS_DISABLE;
  692. RIPMSG0(RIP_VERBOSE, "CtfImmTIMActivate: KACF_DISABLECICERO app compatiblity flag is ON.");
  693. return hr;
  694. }
  695. if (RtlIsThreadWithinLoaderCallout())
  696. {
  697. RIPMSG0(RIP_VERBOSE, "CtfImmTIMActivate: we're in DllMain().");
  698. return hr;
  699. }
  700. if (_InsideLoaderLock()) {
  701. RIPMSG0(RIP_VERBOSE, "CtfImmTIMActivate: we're in DllMain.");
  702. return hr;
  703. }
  704. if (IS_CICERO_ENABLED_AND_NOT16BIT()) {
  705. HINSTANCE hCtf = NULL;
  706. if (IS_IME_KBDLAYOUT(hKL)) {
  707. LANGID lg = LOWORD(HandleToUlong(hKL));
  708. hKL = (HKL)LongToHandle( MAKELONG(lg, lg) );
  709. }
  710. if (!ImmLoadIME(hKL)) {
  711. //
  712. RIPMSG1(RIP_VERBOSE, "CtfImmTIMActivate: ImmLoadIME=%lx fail.", hKL);
  713. //
  714. // Cicero keyboard layout doesn't loaded yet.
  715. // MSCTF ! TF_InvalidAssemblyListCacheIfExist load Cicero assembly.
  716. //
  717. hCtf = LoadLibrary(TEXT("msctf.dll"));
  718. if (hCtf) {
  719. typedef BOOL (WINAPI* PFNINVALIDASSEMBLY)();
  720. PFNINVALIDASSEMBLY pfn;
  721. pfn = (PFNINVALIDASSEMBLY)GetProcAddress(hCtf, "TF_InvalidAssemblyListCacheIfExist");
  722. if (pfn) {
  723. pfn();
  724. }
  725. }
  726. }
  727. /*
  728. * Initialize COM for Cicero IME.
  729. */
  730. CtfImmCoInitialize();
  731. if ( (GetClientInfo()->CI_flags & CI_CUAS_COINIT_CALLED) &&
  732. ! (GetClientInfo()->CI_flags & CI_CUAS_TIM_ACTIVATED)) {
  733. /*
  734. * Create and Activate TIM
  735. */
  736. hr = Internal_CtfImeCreateThreadMgr();
  737. if (SUCCEEDED(hr)) {
  738. GetClientInfo()->CI_flags |= CI_CUAS_TIM_ACTIVATED;
  739. RIPMSG0(RIP_VERBOSE, "CtfImmTIMActivate: Succeeded CtfImeCreateThreadMgr.");
  740. }
  741. else {
  742. RIPMSG0(RIP_WARNING, "CtfImmTIMActivate: Fail CtfImeCreateThreadMgr.");
  743. }
  744. }
  745. if (hCtf) {
  746. FreeLibrary(hCtf);
  747. }
  748. }
  749. return hr;
  750. }
  751. //+---------------------------------------------------------------------------
  752. //
  753. // CtfImmTIMCreateInputContext
  754. //
  755. //----------------------------------------------------------------------------
  756. HRESULT
  757. CtfImmTIMCreateInputContext(
  758. HIMC hImc)
  759. {
  760. PCLIENTIMC pClientImc;
  761. HRESULT hr = S_FALSE;
  762. DWORD dwThreadId;
  763. if (GetClientInfo()->CI_flags & CI_CUAS_AIMM12ACTIVATED)
  764. {
  765. if ((pClientImc = ImmLockClientImc(hImc)) == NULL)
  766. return E_FAIL;
  767. /*
  768. * check fCtfImeContext first
  769. */
  770. if (pClientImc->fCtfImeContext)
  771. goto Exit;
  772. pClientImc->fCtfImeContext = TRUE;
  773. hr = CtfAImmCreateInputContext(hImc);
  774. if (SUCCEEDED(hr)) {
  775. RIPMSG0(RIP_VERBOSE, "CtfImmTIMCreateInputContext: Succeeded CtfImeCreateInputContext.");
  776. }
  777. else {
  778. pClientImc->fCtfImeContext = FALSE;
  779. RIPMSG0(RIP_WARNING, "CtfImmTIMCreateInputContext: Fail CtfImeCreateInputContext.");
  780. }
  781. goto Exit;
  782. }
  783. if (!(GetClientInfo()->CI_flags & CI_CUAS_TIM_ACTIVATED))
  784. {
  785. //
  786. // Tim is not activated. We don't have to create the InputContext.
  787. //
  788. return S_OK;
  789. }
  790. if ((pClientImc = ImmLockClientImc(hImc)) == NULL)
  791. return E_FAIL;
  792. /*
  793. * check fCtfImeContext first
  794. */
  795. if (pClientImc->fCtfImeContext)
  796. goto Exit;
  797. dwThreadId = GetInputContextThread(hImc);
  798. if (dwThreadId != GetCurrentThreadId())
  799. goto Exit;
  800. if (IS_CICERO_ENABLED_AND_NOT16BIT()) {
  801. /*
  802. * Set fCtfImeContext before calling ctfime to avoid recursion
  803. * call.
  804. */
  805. pClientImc->fCtfImeContext = TRUE;
  806. /*
  807. * Create Input Context
  808. */
  809. hr = Internal_CtfImeCreateInputContext(hImc);
  810. if (SUCCEEDED(hr)) {
  811. RIPMSG0(RIP_VERBOSE, "CtfImmTIMCreateInputContext: Succeeded CtfImeCreateInputContext.");
  812. }
  813. else {
  814. pClientImc->fCtfImeContext = FALSE;
  815. RIPMSG0(RIP_WARNING, "CtfImmTIMCreateInputContext: Fail CtfImeCreateInputContext.");
  816. }
  817. }
  818. Exit:
  819. ImmUnlockClientImc(pClientImc);
  820. return hr;
  821. }
  822. //+---------------------------------------------------------------------------
  823. //
  824. // CtfImmTIMDestroyInputContext
  825. //
  826. //----------------------------------------------------------------------------
  827. HRESULT
  828. CtfImmTIMDestroyInputContext(
  829. HIMC hImc)
  830. {
  831. HRESULT hr = E_NOINTERFACE;
  832. if (IS_CICERO_ENABLED_AND_NOT16BIT()) {
  833. /*
  834. * Destroy Input Context.
  835. */
  836. hr = Internal_CtfImeDestroyInputContext(hImc);
  837. if (SUCCEEDED(hr)) {
  838. RIPMSG0(RIP_VERBOSE, "CtfImmTIMDestroyInputContext: Succeeded CtfImeDestroyInputContext.");
  839. }
  840. else {
  841. RIPMSG0(RIP_WARNING, "CtfImmTIMDestroyInputContext: Fail CtfImeDestroyInputContext.");
  842. }
  843. }
  844. return hr;
  845. }
  846. //+---------------------------------------------------------------------------
  847. //
  848. // CtfImmRestoreToolbarWnd
  849. //
  850. //----------------------------------------------------------------------------
  851. void
  852. CtfImmRestoreToolbarWnd(
  853. DWORD dwStatus)
  854. {
  855. ITfLangBarMgr* plbm;
  856. if (SUCCEEDED(Internal_TF_CreateLangBarMgr(&plbm)))
  857. {
  858. if (dwStatus)
  859. {
  860. ITfLangBarMgr_ShowFloating(plbm, dwStatus);
  861. }
  862. ITfLangBarMgr_Release(plbm);
  863. }
  864. return;
  865. }
  866. //+---------------------------------------------------------------------------
  867. //
  868. // CtfImmHideToolbarWnd
  869. //
  870. //----------------------------------------------------------------------------
  871. DWORD
  872. CtfImmHideToolbarWnd()
  873. {
  874. ITfLangBarMgr* plbm;
  875. DWORD _dwPrev = 0;
  876. if (SUCCEEDED(Internal_TF_CreateLangBarMgr(&plbm)))
  877. {
  878. if (SUCCEEDED(ITfLangBarMgr_GetShowFloatingStatus(plbm, &_dwPrev)))
  879. {
  880. BOOL fHide = TRUE;
  881. if (_dwPrev & TF_SFT_DESKBAND)
  882. fHide = FALSE;
  883. //
  884. // mask for show/hide
  885. //
  886. _dwPrev &= (TF_SFT_SHOWNORMAL |
  887. TF_SFT_DOCK |
  888. TF_SFT_MINIMIZED |
  889. TF_SFT_HIDDEN);
  890. if (fHide)
  891. ITfLangBarMgr_ShowFloating(plbm, TF_SFT_HIDDEN);
  892. }
  893. ITfLangBarMgr_Release(plbm);
  894. }
  895. return _dwPrev;
  896. }
  897. //+---------------------------------------------------------------------------
  898. //
  899. // CtfImmGetGuidAtom
  900. //
  901. //----------------------------------------------------------------------------
  902. HRESULT
  903. CtfImmGetGuidAtom(HIMC hImc, BYTE bAttr, DWORD* pGuidAtom)
  904. {
  905. HRESULT hr = E_FAIL;
  906. *pGuidAtom = 0;
  907. if (IS_CICERO_ENABLED_AND_NOT16BIT()) {
  908. PIMEDPI pImeDpi;
  909. DWORD dwImcThreadId = (DWORD)NtUserQueryInputContext(hImc, InputContextThread);
  910. HKL hKL = GetKeyboardLayout(dwImcThreadId);
  911. if (IS_IME_KBDLAYOUT(hKL)) {
  912. RIPMSG1(RIP_WARNING, "CtfImmGetGuidAtom: hKL=%lx.", hKL);
  913. return FALSE;
  914. }
  915. pImeDpi = FindOrLoadImeDpi(hKL);
  916. if (pImeDpi == NULL) {
  917. RIPMSG0(RIP_WARNING, "CtfImmGetGuidAtom: no pImeDpi entry.");
  918. }
  919. else {
  920. /*
  921. * Get GUID atom value
  922. */
  923. hr = (*pImeDpi->pfn.CtfImeGetGuidAtom)(hImc, bAttr, pGuidAtom);
  924. if (SUCCEEDED(hr)) {
  925. RIPMSG0(RIP_VERBOSE, "CtfImmGetGuidAtom: Succeeded CtfImeGetGuidAtom.");
  926. }
  927. else {
  928. RIPMSG0(RIP_WARNING, "CtfImmGetGuidAtom: Fail CtfImeGetGuidAtom.");
  929. }
  930. ImmUnlockImeDpi(pImeDpi);
  931. }
  932. }
  933. return hr;
  934. }
  935. //+---------------------------------------------------------------------------
  936. //
  937. // CtfImmIsGuidMapEnable
  938. //
  939. //----------------------------------------------------------------------------
  940. BOOL
  941. CtfImmIsGuidMapEnable(HIMC hImc)
  942. {
  943. BOOL ret = FALSE;
  944. if (IS_CICERO_ENABLED_AND_NOT16BIT()) {
  945. PIMEDPI pImeDpi;
  946. DWORD dwImcThreadId = (DWORD)NtUserQueryInputContext(hImc, InputContextThread);
  947. HKL hKL = GetKeyboardLayout(dwImcThreadId);
  948. if (IS_IME_KBDLAYOUT(hKL)) {
  949. RIPMSG1(RIP_WARNING, "CtfImmIsGuidMapEnable: hKL=%lx.", hKL);
  950. return FALSE;
  951. }
  952. pImeDpi = FindOrLoadImeDpi(hKL);
  953. if (pImeDpi == NULL) {
  954. RIPMSG0(RIP_WARNING, "CtfImmIsGuidMapEnable: no pImeDpi entry.");
  955. }
  956. else {
  957. /*
  958. * Get GUID atom value
  959. */
  960. ret = (*pImeDpi->pfn.CtfImeIsGuidMapEnable)(hImc);
  961. ImmUnlockImeDpi(pImeDpi);
  962. }
  963. }
  964. return ret;
  965. }
  966. //+---------------------------------------------------------------------------
  967. //
  968. // CtfImmSetAppCompatFlags
  969. //
  970. //----------------------------------------------------------------------------
  971. DWORD g_aimm_compat_flags = 0;
  972. VOID
  973. CtfImmSetAppCompatFlags(
  974. DWORD dwFlag)
  975. {
  976. if (dwFlag & ~(IMECOMPAT_AIMM_LEGACY_CLSID |
  977. IMECOMPAT_AIMM_TRIDENT55 |
  978. IMECOMPAT_AIMM12_TRIDENT |
  979. IMECOMPAT_AIMM12))
  980. {
  981. return;
  982. }
  983. g_aimm_compat_flags = dwFlag;
  984. }
  985. //+---------------------------------------------------------------------------
  986. //
  987. // ActivateOrDeactivateTIM
  988. //
  989. //----------------------------------------------------------------------------
  990. HRESULT
  991. ActivateOrDeactivateTIM(
  992. BOOL fActivate)
  993. {
  994. HRESULT hr = S_OK;
  995. if (IS_CICERO_ENABLED_AND_NOT16BIT()) {
  996. if (GetClientInfo()->CI_flags & CI_CUAS_COINIT_CALLED) {
  997. if (! fActivate) {
  998. /*
  999. * Deactivate TIM
  1000. */
  1001. if (GetClientInfo()->CI_flags & CI_CUAS_TIM_ACTIVATED) {
  1002. hr = Internal_CtfImeDestroyThreadMgr();
  1003. if (SUCCEEDED(hr)) {
  1004. GetClientInfo()->CI_flags &= ~CI_CUAS_TIM_ACTIVATED;
  1005. RIPMSG0(RIP_VERBOSE, "CtfImmLastEnabledWndDestroy: Succeeded CtfImeDestroyThreadMgr.");
  1006. }
  1007. else {
  1008. RIPMSG0(RIP_WARNING, "CtfImmLastEnabledWndDestroy: Fail CtfImeDestroyThreadMgr.");
  1009. }
  1010. }
  1011. }
  1012. else {
  1013. /*
  1014. * Activate TIM
  1015. */
  1016. if (! (GetClientInfo()->CI_flags & CI_CUAS_TIM_ACTIVATED)) {
  1017. hr = Internal_CtfImeCreateThreadMgr();
  1018. if (SUCCEEDED(hr)) {
  1019. GetClientInfo()->CI_flags |= CI_CUAS_TIM_ACTIVATED;
  1020. RIPMSG0(RIP_VERBOSE, "CtfImmLastEnabledWndDestroy: Succeeded CtfImeDestroyThreadMgr.");
  1021. }
  1022. else {
  1023. RIPMSG0(RIP_WARNING, "CtfImmLastEnabledWndDestroy: Fail CtfImeDestroyThreadMgr.");
  1024. }
  1025. }
  1026. }
  1027. }
  1028. }
  1029. return hr;
  1030. }
  1031. //+---------------------------------------------------------------------------
  1032. //
  1033. // CtfImmLastEnabledWndDestroy
  1034. // LPARAM 0 = Deactivate TIM.
  1035. // ! 0 = Activate TIM.
  1036. //
  1037. //----------------------------------------------------------------------------
  1038. HRESULT
  1039. CtfImmLastEnabledWndDestroy(
  1040. LPARAM lParam)
  1041. {
  1042. return ActivateOrDeactivateTIM(lParam ? TRUE : FALSE);
  1043. }
  1044. //+---------------------------------------------------------------------------
  1045. //
  1046. // ImmSetLangBand
  1047. //
  1048. //----------------------------------------------------------------------------
  1049. // TM_LANGUAGEBAND is defined in "shell\inc\trayp.h"
  1050. #define TM_LANGUAGEBAND WM_USER+0x105
  1051. typedef struct _LANG_BAND {
  1052. HWND hwndTray;
  1053. BOOL fLangBand;
  1054. } LANG_BAND;
  1055. DWORD
  1056. DelaySetLangBand(
  1057. LANG_BAND* langband)
  1058. {
  1059. HWND hwndIME;
  1060. //
  1061. // Delay 3000msec.
  1062. // If this delay value is not enough, Explorer takes CPU power 100%.
  1063. // printui!CTrayNotify::_ResetAll
  1064. //
  1065. Sleep(3000);
  1066. hwndIME = ImmGetDefaultIMEWnd(langband->hwndTray);
  1067. if (hwndIME) {
  1068. DWORD_PTR dwResult;
  1069. LRESULT lResult = (LRESULT)0;
  1070. lResult = SendMessageTimeout(hwndIME,
  1071. WM_IME_SYSTEM,
  1072. langband->fLangBand ? IMS_SETLANGBAND : IMS_RESETLANGBAND,
  1073. (LPARAM)langband->hwndTray,
  1074. SMTO_ABORTIFHUNG | SMTO_BLOCK,
  1075. 5000,
  1076. &dwResult);
  1077. //
  1078. // Checking the language band setting fail case
  1079. //
  1080. if (!lResult || dwResult != langband->fLangBand)
  1081. {
  1082. // UserAssert(0);
  1083. }
  1084. }
  1085. ImmLocalFree(langband);
  1086. return 0;
  1087. }
  1088. LRESULT
  1089. CtfImmSetLangBand(
  1090. HWND hwndTray,
  1091. BOOL fLangBand)
  1092. {
  1093. DWORD_PTR dwResult = 0;
  1094. PWND pwnd;
  1095. // check if the window of the Explorer Tray is valid
  1096. if ((pwnd = ValidateHwnd(hwndTray)) == NULL) {
  1097. RIPMSG1(RIP_WARNING, "CtfImmSetLangBand: Invalid hwndTray %lx.", hwndTray);
  1098. } else {
  1099. if (TestWF(pwnd, WFISINITIALIZED)) { // TRUE if the Explorer Tray is initialized
  1100. LRESULT lResult = (LRESULT)0;
  1101. lResult = SendMessageTimeout(hwndTray,
  1102. TM_LANGUAGEBAND,
  1103. 0,
  1104. fLangBand,
  1105. SMTO_ABORTIFHUNG | SMTO_BLOCK,
  1106. 5000,
  1107. &dwResult);
  1108. //
  1109. // Checking the language band setting fail case
  1110. //
  1111. if (!lResult || dwResult != fLangBand)
  1112. {
  1113. // UserAssert(0);
  1114. }
  1115. }
  1116. else {
  1117. LANG_BAND* langband = (LANG_BAND*) ImmLocalAlloc(0, sizeof(LANG_BAND));
  1118. if (langband != NULL) {
  1119. HANDLE hThread;
  1120. DWORD ThreadId;
  1121. langband->hwndTray = hwndTray;
  1122. langband->fLangBand = fLangBand;
  1123. hThread = CreateThread(NULL,
  1124. 0,
  1125. DelaySetLangBand,
  1126. langband,
  1127. 0,
  1128. &ThreadId);
  1129. if (hThread) {
  1130. CloseHandle(hThread);
  1131. }
  1132. }
  1133. }
  1134. }
  1135. return dwResult;
  1136. }
  1137. BOOL
  1138. CtfImmIsCiceroEnabled()
  1139. {
  1140. return IS_CICERO_ENABLED();
  1141. }
  1142. BOOL
  1143. CtfImmIsCiceroStartedInThread()
  1144. {
  1145. return (GetClientInfo()->CI_flags & CI_CUAS_MSCTF_RUNNING) ? TRUE : FALSE;
  1146. }
  1147. HRESULT
  1148. CtfImmSetCiceroStartInThread(BOOL fSet)
  1149. {
  1150. if (fSet)
  1151. GetClientInfo()->CI_flags |= CI_CUAS_MSCTF_RUNNING;
  1152. else
  1153. GetClientInfo()->CI_flags &= ~CI_CUAS_MSCTF_RUNNING;
  1154. return S_OK;
  1155. }
  1156. BOOL
  1157. IsCUASEnabled()
  1158. {
  1159. LONG lRet;
  1160. HKEY hKeyCtf;
  1161. DWORD dwType;
  1162. DWORD dwCUAS;
  1163. DWORD dwTmp;
  1164. lRet = RegOpenKey(HKEY_LOCAL_MACHINE, gszRegCtfShared, &hKeyCtf);
  1165. if ( lRet != ERROR_SUCCESS ) {
  1166. return FALSE;
  1167. }
  1168. dwType = 0;
  1169. dwCUAS = 0;
  1170. dwTmp = sizeof(DWORD);
  1171. lRet = RegQueryValueEx(hKeyCtf,
  1172. gszValCUASEnable,
  1173. NULL,
  1174. &dwType,
  1175. (LPBYTE)&dwCUAS,
  1176. &dwTmp);
  1177. RegCloseKey(hKeyCtf);
  1178. if ( lRet != ERROR_SUCCESS || dwType != REG_DWORD) {
  1179. return FALSE;
  1180. }
  1181. return (BOOL)dwCUAS;
  1182. }
  1183. //+---------------------------------------------------------------------------
  1184. //
  1185. // ImmDisableTextFrameService
  1186. //
  1187. //----------------------------------------------------------------------------
  1188. BOOL
  1189. ImmDisableTextFrameService(DWORD idThread)
  1190. {
  1191. HRESULT hr = S_OK;
  1192. if (idThread == -1)
  1193. {
  1194. // Text frame service processing is disabled for all the thread in the current process
  1195. g_disable_CUAS_flag = TRUE;
  1196. }
  1197. if ((idThread == 0 || g_disable_CUAS_flag) &&
  1198. (! (GetClientInfo()->CI_flags & CI_CUAS_DISABLE)))
  1199. {
  1200. /*
  1201. * set client info flag.
  1202. */
  1203. GetClientInfo()->CI_flags |= CI_CUAS_DISABLE;
  1204. if (IS_CICERO_ENABLED_AND_NOT16BIT()) {
  1205. if (GetClientInfo()->CI_flags & CI_CUAS_COINIT_CALLED) {
  1206. /*
  1207. * Deactivate TIM
  1208. */
  1209. if (GetClientInfo()->CI_flags & CI_CUAS_TIM_ACTIVATED) {
  1210. hr = Internal_CtfImeDestroyThreadMgr();
  1211. if (SUCCEEDED(hr)) {
  1212. GetClientInfo()->CI_flags &= ~CI_CUAS_TIM_ACTIVATED;
  1213. RIPMSG0(RIP_VERBOSE, "ImmDisableTextFrameService: Succeeded CtfImeDestroyThreadMgr.");
  1214. }
  1215. else {
  1216. RIPMSG0(RIP_WARNING, "ImmDisableTextFrameService: Fail CtfImeDestroyThreadMgr.");
  1217. }
  1218. if (SUCCEEDED(hr)) {
  1219. /*
  1220. * CoUninitialize
  1221. */
  1222. CtfImmCoUninitialize();
  1223. }
  1224. }
  1225. }
  1226. }
  1227. }
  1228. return hr == S_OK ? TRUE : FALSE;
  1229. }
  1230. BOOL
  1231. CtfImmIsTextFrameServiceDisabled()
  1232. {
  1233. return (GetClientInfo()->CI_flags & CI_CUAS_DISABLE) ? TRUE : FALSE;
  1234. }
  1235. BOOL
  1236. IsDisabledTextServices()
  1237. {
  1238. static const TCHAR c_szCTFKey[] = TEXT("SOFTWARE\\Microsoft\\CTF");
  1239. static const TCHAR c_szDiableTim[] = TEXT("Disable Thread Input Manager");
  1240. HKEY hKey;
  1241. if (RegOpenKey(HKEY_CURRENT_USER, c_szCTFKey, &hKey) == ERROR_SUCCESS)
  1242. {
  1243. DWORD cb;
  1244. DWORD dwDisableTim = 0;
  1245. cb = sizeof(DWORD);
  1246. RegQueryValueEx(hKey,
  1247. c_szDiableTim,
  1248. NULL,
  1249. NULL,
  1250. (LPBYTE)&dwDisableTim,
  1251. &cb);
  1252. RegCloseKey(hKey);
  1253. //
  1254. // Ctfmon disabling flag is set.
  1255. //
  1256. if (dwDisableTim)
  1257. return TRUE;
  1258. }
  1259. return FALSE;
  1260. }
  1261. BOOL
  1262. IsInteractiveUserLogon()
  1263. {
  1264. PSID InteractiveSid;
  1265. BOOL bCheckSucceeded;
  1266. BOOL bAmInteractive = FALSE;
  1267. SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
  1268. if (!AllocateAndInitializeSid(&NtAuthority,
  1269. 1,
  1270. SECURITY_INTERACTIVE_RID,
  1271. 0, 0, 0, 0, 0, 0, 0,
  1272. &InteractiveSid))
  1273. {
  1274. return FALSE;
  1275. }
  1276. //
  1277. // This checking is for logged on user or not. So we can blcok running
  1278. // ctfmon.exe process from non-authorized user.
  1279. //
  1280. bCheckSucceeded = CheckTokenMembership(NULL,
  1281. InteractiveSid,
  1282. &bAmInteractive);
  1283. if (InteractiveSid)
  1284. FreeSid(InteractiveSid);
  1285. return (bCheckSucceeded && bAmInteractive);
  1286. }
  1287. //+---------------------------------------------------------------------------
  1288. //
  1289. // IsRunningInMsoobe()
  1290. //
  1291. //----------------------------------------------------------------------------
  1292. BOOL IsRunningInMsoobe()
  1293. {
  1294. static const TCHAR c_szMsoobeModule[] = TEXT("msoobe.exe");
  1295. TCHAR szFileName[MAX_PATH];
  1296. TCHAR szModuleName[MAX_PATH];
  1297. LPTSTR pszFilePart = NULL;
  1298. if (GetModuleFileName(NULL, szFileName, sizeof(szFileName)/sizeof(szFileName[0])) == 0)
  1299. return FALSE;
  1300. GetFullPathName(szFileName,
  1301. sizeof(szFileName)/sizeof(szFileName[0]),
  1302. szModuleName,
  1303. &pszFilePart);
  1304. if (pszFilePart == NULL)
  1305. return FALSE;
  1306. if (lstrcmpiW(pszFilePart, c_szMsoobeModule) == 0)
  1307. return TRUE;
  1308. return FALSE;
  1309. }
  1310. //+---------------------------------------------------------------------------
  1311. //
  1312. // LoadCtfIme
  1313. //
  1314. //----------------------------------------------------------------------------
  1315. BOOL CheckAndApplyAppCompat(LPWSTR wszImeFile);
  1316. typedef HRESULT (CALLBACK* PFNCREATETHREADMGR)();
  1317. typedef HRESULT (CALLBACK* PFNDESTROYTHREADMGR)();
  1318. typedef HRESULT (CALLBACK* PFNCREATEINPUTCONTEXT)(HIMC);
  1319. typedef HRESULT (CALLBACK* PFNDESTROYINPUTCONTEXT)(HIMC);
  1320. typedef HRESULT (CALLBACK* PFNSETACTIVECONTEXTALWAYS)(HIMC, BOOL, HWND, HKL);
  1321. typedef BOOL (CALLBACK* PFNPROCESSCICHOTKEY)(HIMC, UINT, LPARAM);
  1322. typedef LRESULT (CALLBACK* PFNDISPATCHDEFIMEMESSAGE)(HWND, UINT, WPARAM, LPARAM);
  1323. typedef BOOL (CALLBACK* PFNIMEISIME)(HKL);
  1324. PFNCREATETHREADMGR g_pfnCtfImeCreateThreadMgr = NULL;
  1325. PFNDESTROYTHREADMGR g_pfnCtfImeDestroyThreadMgr = NULL;
  1326. PFNCREATEINPUTCONTEXT g_pfnCtfImeCreateInputContext = NULL;
  1327. PFNDESTROYINPUTCONTEXT g_pfnCtfImeDestroyInputContext= NULL;
  1328. PFNSETACTIVECONTEXTALWAYS g_pfnCtfImeSetActiveContextAlways= NULL;
  1329. PFNPROCESSCICHOTKEY g_pfnCtfImeProcessCicHotkey = NULL;
  1330. PFNDISPATCHDEFIMEMESSAGE g_pfnCtfImeDispatchDefImeMessage = NULL;
  1331. PFNIMEISIME g_pfnCtfImeIsIME = NULL;
  1332. #define GET_CTFIMEPROC(x) \
  1333. if (!(g_pfn##x = (PVOID) GetProcAddress(g_hCtfIme, #x))) { \
  1334. RIPMSG0(RIP_WARNING, "LoadCtfIme: " #x " not supported"); \
  1335. goto LoadCtfIme_ErrOut; }
  1336. HMODULE g_hCtfIme = NULL;
  1337. HMODULE LoadCtfIme()
  1338. {
  1339. IMEINFOEX iiex;
  1340. RtlEnterCriticalSection(&gcsImeDpi);
  1341. if (g_hCtfIme)
  1342. goto Exit;
  1343. if (ImmLoadLayout((HKL)0x04090409, &iiex)) {
  1344. WCHAR wszImeFile[MAX_PATH];
  1345. GetSystemPathName(wszImeFile, iiex.wszImeFile, MAX_PATH);
  1346. if (!CheckAndApplyAppCompat(wszImeFile)) {
  1347. RIPMSG1(RIP_WARNING, "LoadCtfIme: IME (%ws) blocked by appcompat", wszImeFile);
  1348. }
  1349. else {
  1350. g_hCtfIme = LoadLibraryW(wszImeFile);
  1351. if (g_hCtfIme) {
  1352. GET_CTFIMEPROC(CtfImeCreateThreadMgr);
  1353. GET_CTFIMEPROC(CtfImeDestroyThreadMgr);
  1354. GET_CTFIMEPROC(CtfImeCreateInputContext);
  1355. GET_CTFIMEPROC(CtfImeDestroyInputContext);
  1356. GET_CTFIMEPROC(CtfImeSetActiveContextAlways);
  1357. GET_CTFIMEPROC(CtfImeProcessCicHotkey);
  1358. GET_CTFIMEPROC(CtfImeDispatchDefImeMessage);
  1359. GET_CTFIMEPROC(CtfImeIsIME);
  1360. }
  1361. }
  1362. }
  1363. goto Exit;
  1364. LoadCtfIme_ErrOut:
  1365. if (g_hCtfIme) {
  1366. FreeLibrary(g_hCtfIme);
  1367. g_hCtfIme = NULL;
  1368. }
  1369. Exit:
  1370. RtlLeaveCriticalSection(&gcsImeDpi);
  1371. return g_hCtfIme;
  1372. }
  1373. //+---------------------------------------------------------------------------
  1374. //
  1375. // CtfAImmCreateInputContext
  1376. //
  1377. //----------------------------------------------------------------------------
  1378. HRESULT CtfAImmCreateInputContext(HIMC himc)
  1379. {
  1380. return Internal_CtfImeCreateInputContext(himc);
  1381. }
  1382. //+---------------------------------------------------------------------------
  1383. //
  1384. // EnumIMC
  1385. //
  1386. //----------------------------------------------------------------------------
  1387. BOOL EnumIMC(HIMC hIMC, LPARAM lParam)
  1388. {
  1389. UNREFERENCED_PARAMETER(lParam);
  1390. CtfAImmCreateInputContext(hIMC);
  1391. return TRUE;
  1392. }
  1393. //+---------------------------------------------------------------------------
  1394. //
  1395. // CtfAImmActivate
  1396. //
  1397. //----------------------------------------------------------------------------
  1398. HRESULT CtfAImmActivate(HMODULE* phMod)
  1399. {
  1400. HRESULT hr = E_FAIL;
  1401. HMODULE hCtfIme = LoadCtfIme();
  1402. hr = Internal_CtfImeCreateThreadMgr();
  1403. if (hr == S_OK)
  1404. {
  1405. GetClientInfo()->CI_flags |= CI_CUAS_AIMM12ACTIVATED;
  1406. /*
  1407. * reset client info flag.
  1408. * Bug#525583 - Reset CU_CUAS_DISABLE flag before create
  1409. * the input context.
  1410. */
  1411. GetClientInfo()->CI_flags &= ~CI_CUAS_DISABLE;
  1412. ImmEnumInputContext(0, EnumIMC, 0);
  1413. }
  1414. if (phMod)
  1415. *phMod = hCtfIme;
  1416. return hr;
  1417. }
  1418. //+---------------------------------------------------------------------------
  1419. //
  1420. // CtfAImmDectivate
  1421. //
  1422. //----------------------------------------------------------------------------
  1423. HRESULT CtfAImmDeactivate(HMODULE hMod)
  1424. {
  1425. HRESULT hr = E_FAIL;
  1426. //
  1427. // Load CTFIME and destroy TIM.
  1428. //
  1429. if (hMod)
  1430. {
  1431. hr = Internal_CtfImeDestroyThreadMgr();
  1432. if (hr == S_OK)
  1433. {
  1434. GetClientInfo()->CI_flags &= ~CI_CUAS_AIMM12ACTIVATED;
  1435. /*
  1436. * set client info flag.
  1437. */
  1438. GetClientInfo()->CI_flags |= CI_CUAS_DISABLE;
  1439. }
  1440. //
  1441. // Win BUG: 611569
  1442. //
  1443. // Don't call FreeLibrary because LoadCtfIme() hold CTFIME module handle in global.
  1444. //
  1445. // FreeLibrary(hMod);
  1446. }
  1447. return hr;
  1448. }
  1449. //+---------------------------------------------------------------------------
  1450. //
  1451. // CtfAImmIsIME
  1452. //
  1453. //----------------------------------------------------------------------------
  1454. BOOL CtfAImmIsIME(HKL hkl)
  1455. {
  1456. if (LoadCtfIme())
  1457. return (g_pfnCtfImeIsIME)(hkl);
  1458. return ImmIsIME(hkl);
  1459. }
  1460. //+---------------------------------------------------------------------------
  1461. //
  1462. // CtfImmDispatchDefImeMessage
  1463. //
  1464. //----------------------------------------------------------------------------
  1465. LRESULT CtfImmDispatchDefImeMessage(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  1466. {
  1467. if (RtlDllShutdownInProgress() || _InsideLoaderLock())
  1468. return 0;
  1469. if (LoadCtfIme())
  1470. {
  1471. return (g_pfnCtfImeDispatchDefImeMessage)(hwnd, message, wParam, lParam);
  1472. }
  1473. return 0;
  1474. }
  1475. //+---------------------------------------------------------------------------
  1476. //
  1477. // Internal_CtfImeCreateThreadMgr
  1478. //
  1479. //----------------------------------------------------------------------------
  1480. HRESULT Internal_CtfImeCreateThreadMgr()
  1481. {
  1482. if (!LoadCtfIme())
  1483. return E_FAIL;
  1484. return (g_pfnCtfImeCreateThreadMgr)();
  1485. }
  1486. //+---------------------------------------------------------------------------
  1487. //
  1488. // Internal_CtfImeDestroyThreadMgr
  1489. //
  1490. //----------------------------------------------------------------------------
  1491. HRESULT Internal_CtfImeDestroyThreadMgr()
  1492. {
  1493. if (!LoadCtfIme())
  1494. return E_FAIL;
  1495. return (g_pfnCtfImeDestroyThreadMgr)();
  1496. }
  1497. //+---------------------------------------------------------------------------
  1498. //
  1499. // Internal_CtfImeProcessCicHotkey
  1500. //
  1501. //----------------------------------------------------------------------------
  1502. BOOL Internal_CtfImeProcessCicHotkey(HIMC hIMC, UINT uVKey, LPARAM lParam)
  1503. {
  1504. if (!LoadCtfIme())
  1505. return FALSE;
  1506. return (g_pfnCtfImeProcessCicHotkey)(hIMC, uVKey, lParam);
  1507. }
  1508. //+---------------------------------------------------------------------------
  1509. //
  1510. // Internal_CtfImeCreateInputContext
  1511. //
  1512. //----------------------------------------------------------------------------
  1513. HRESULT Internal_CtfImeCreateInputContext(HIMC himc)
  1514. {
  1515. if (!LoadCtfIme())
  1516. return E_FAIL;
  1517. return (g_pfnCtfImeCreateInputContext)(himc);
  1518. }
  1519. //+---------------------------------------------------------------------------
  1520. //
  1521. // Internal_CtfImeDestroyInputContext
  1522. //
  1523. //----------------------------------------------------------------------------
  1524. HRESULT Internal_CtfImeDestroyInputContext(HIMC himc)
  1525. {
  1526. if (!LoadCtfIme())
  1527. return E_FAIL;
  1528. return (g_pfnCtfImeDestroyInputContext)(himc);
  1529. }
  1530. //+---------------------------------------------------------------------------
  1531. //
  1532. // Internal_CtfImeSetActiveContextAlways
  1533. //
  1534. //----------------------------------------------------------------------------
  1535. HRESULT Internal_CtfImeSetActiveContextAlways(HIMC himc, BOOL fActive, HWND hwnd, HKL hkl)
  1536. {
  1537. if (!LoadCtfIme())
  1538. return E_FAIL;
  1539. return (g_pfnCtfImeSetActiveContextAlways)(himc, fActive, hwnd, hkl);
  1540. }
  1541. #else
  1542. void CtfImmGetGuidAtom() { }
  1543. void CtfImmHideToolbarWnd() { }
  1544. void CtfImmIsGuidMapEnable() { }
  1545. void CtfImmRestoreToolbarWnd() { }
  1546. void CtfImmSetAppCompatFlags() { }
  1547. void CtfImmTIMActivate() { }
  1548. void CtfImmIsCiceroEnabled() { }
  1549. void CtfImmDispatchDefImeMessage() { }
  1550. #endif // CUAS_ENABLE