[IMM32][SDK][NTUSER] Implement CtfImmTIMActivate (#6041)

- Add Imm32InitTLS, Imm32AllocateTLS, Imm32GetTLS,
  Imm32GetCoInitCountSkip, Imm32IncCoInitCountSkip, and
  Imm32DecCoInitCountSkip helper functions to
  control the TLS data.
- Introduce "CoInitialize Spy" (ISPY) to manage COM
  initialization status.
- Implement CtfImmCoInitialize and CtfImmCoUninitialize.
- Implement CtfImmEnterCoInitCountSkipMode and
  CtfImmLeaveCoInitCountSkipMode.
- Implement CtfImmLastEnabledWndDestroy,
  ImmDisableTextFrameService, and CtfImmTIMActivate.
CORE-19268
This commit is contained in:
Katayama Hirofumi MZ 2023-11-30 17:22:50 +09:00 committed by GitHub
parent 01a8288d28
commit 931224fbe1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 683 additions and 46 deletions

View file

@ -45,6 +45,6 @@ list(APPEND imm32_rc_deps
add_library(imm32 MODULE ${SOURCE} imm32.rc)
set_module_type(imm32 win32dll UNICODE ENTRYPOINT ImmDllInitialize 12)
set_source_files_properties(imm32.rc PROPERTIES OBJECT_DEPENDS "${imm32_rc_deps}")
target_link_libraries(imm32 wine win32ksys)
target_link_libraries(imm32 wine win32ksys uuid)
add_importlibs(imm32 advapi32 user32 gdi32 kernel32 ntdll)
add_cd_file(TARGET imm32 DESTINATION reactos/system32 FOR all)

View file

@ -6,11 +6,83 @@
*/
#include "precomp.h"
#include <msctf.h>
#include <ctfutb.h>
#include <msctf.h> /* for ITfLangBarMgr */
#include <objidl.h> /* for IInitializeSpy */
WINE_DEFAULT_DEBUG_CHANNEL(imm);
/* FIXME: Use RTL */
static BOOL WINAPI RtlDllShutdownInProgress(VOID)
{
return FALSE;
}
static BOOL Imm32InsideLoaderLock(VOID)
{
return NtCurrentTeb()->ProcessEnvironmentBlock->LoaderLock->OwningThread ==
NtCurrentTeb()->ClientId.UniqueThread;
}
static BOOL
Imm32IsInteractiveUserLogon(VOID)
{
BOOL bOK, IsMember = FALSE;
PSID pSid;
SID_IDENTIFIER_AUTHORITY IdentAuth = { SECURITY_NT_AUTHORITY };
if (!AllocateAndInitializeSid(&IdentAuth, 1, SECURITY_INTERACTIVE_RID,
0, 0, 0, 0, 0, 0, 0, &pSid))
{
ERR("Error: %ld\n", GetLastError());
return FALSE;
}
bOK = CheckTokenMembership(NULL, pSid, &IsMember);
if (pSid)
FreeSid(pSid);
return bOK && IsMember;
}
static BOOL
Imm32IsRunningInMsoobe(VOID)
{
LPWSTR pchFilePart = NULL;
WCHAR Buffer[MAX_PATH], FileName[MAX_PATH];
if (!GetModuleFileNameW(NULL, FileName, _countof(FileName)))
return FALSE;
GetFullPathNameW(FileName, _countof(Buffer), Buffer, &pchFilePart);
if (!pchFilePart)
return FALSE;
return lstrcmpiW(pchFilePart, L"msoobe.exe") == 0;
}
static BOOL
Imm32IsCUASEnabledInRegistry(VOID)
{
HKEY hKey;
LSTATUS error;
DWORD dwType, dwData, cbData;
error = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\CTF\\SystemShared", &hKey);
if (error != ERROR_SUCCESS)
return FALSE;
dwData = 0;
cbData = sizeof(dwData);
error = RegQueryValueExW(hKey, L"CUAS", NULL, &dwType, (LPBYTE)&dwData, &cbData);
RegCloseKey(hKey);
if (error != ERROR_SUCCESS || dwType != REG_DWORD)
return FALSE;
return !!dwData;
}
BOOL
Imm32GetFn(
_Inout_opt_ FARPROC *ppfn,
@ -110,6 +182,8 @@ FN_TF_InvalidAssemblyListCacheIfExist MSCTF_FN(TF_InvalidAssemblyListCacheIfExis
HRESULT Imm32TF_CreateLangBarMgr(_Inout_ ITfLangBarMgr **ppBarMgr)
{
TRACE("TF_CreateLangBarMgr(%p)\n", ppBarMgr);
if (!Imm32GetMsctfFn(TF_CreateLangBarMgr))
return E_FAIL;
@ -118,6 +192,8 @@ HRESULT Imm32TF_CreateLangBarMgr(_Inout_ ITfLangBarMgr **ppBarMgr)
VOID Imm32TF_InvalidAssemblyListCacheIfExist(VOID)
{
TRACE("TF_InvalidAssemblyListCacheIfExist()\n");
if (!Imm32GetMsctfFn(TF_InvalidAssemblyListCacheIfExist))
return;
@ -141,6 +217,9 @@ VOID Imm32TF_InvalidAssemblyListCacheIfExist(VOID)
/* "Active IMM" compatibility flags */
DWORD g_aimm_compat_flags = 0;
/* Disable CUAS? */
BOOL g_disable_CUAS_flag = FALSE;
/* The instance of the CTF IME file */
HINSTANCE g_hCtfIme = NULL;
@ -203,6 +282,384 @@ Imm32CheckAndApplyAppCompat(
return pApphelpCheckIME(pszAppName);
}
/***********************************************************************
* TLS (Thread-Local Storage)
*
* See: TlsAlloc
*/
DWORD g_dwTLSIndex = -1;
/* IMM Thread-Local Storage (TLS) data */
typedef struct IMMTLSDATA
{
IInitializeSpy *pSpy; /* CoInitialize Spy */
DWORD dwUnknown1;
ULARGE_INTEGER uliCookie; /* Spy requires a cookie for revoking */
BOOL bDoCount; /* Is it counting? */
DWORD dwSkipCount; /* The skipped count */
BOOL bUninitializing; /* Is it uninitializing? */
DWORD dwUnknown2;
} IMMTLSDATA, *PIMMTLSDATA;
static VOID
Imm32InitTLS(VOID)
{
RtlEnterCriticalSection(&gcsImeDpi);
if (g_dwTLSIndex == -1)
g_dwTLSIndex = TlsAlloc();
RtlLeaveCriticalSection(&gcsImeDpi);
}
static IMMTLSDATA*
Imm32AllocateTLS(VOID)
{
IMMTLSDATA *pData;
if (g_dwTLSIndex == -1)
return NULL;
pData = (IMMTLSDATA*)TlsGetValue(g_dwTLSIndex);
if (pData)
return pData;
pData = (IMMTLSDATA*)ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(IMMTLSDATA));
if (IS_NULL_UNEXPECTEDLY(pData))
return NULL;
if (IS_FALSE_UNEXPECTEDLY(TlsSetValue(g_dwTLSIndex, pData)))
{
ImmLocalFree(pData);
return NULL;
}
return pData;
}
static IMMTLSDATA*
Imm32GetTLS(VOID)
{
if (g_dwTLSIndex == -1)
return NULL;
return (IMMTLSDATA*)TlsGetValue(g_dwTLSIndex);
}
/* Get */
static DWORD
Imm32GetCoInitCountSkip(VOID)
{
IMMTLSDATA *pData = Imm32GetTLS();
if (!pData)
return 0;
return pData->dwSkipCount;
}
/* Increment */
static DWORD
Imm32IncCoInitCountSkip(VOID)
{
IMMTLSDATA *pData;
DWORD dwOldSkipCount;
pData = Imm32GetTLS();
if (!pData)
return 0;
dwOldSkipCount = pData->dwSkipCount;
if (pData->bDoCount)
pData->dwSkipCount = dwOldSkipCount + 1;
return dwOldSkipCount;
}
/* Decrement */
static DWORD
Imm32DecCoInitCountSkip(VOID)
{
DWORD dwSkipCount;
IMMTLSDATA *pData;
pData = Imm32GetTLS();;
if (!pData)
return 0;
dwSkipCount = pData->dwSkipCount;
if (pData->bDoCount)
{
if (dwSkipCount)
pData->dwSkipCount = dwSkipCount - 1;
}
return dwSkipCount;
}
/***********************************************************************
* CtfImmEnterCoInitCountSkipMode (IMM32.@)
*/
VOID WINAPI CtfImmEnterCoInitCountSkipMode(VOID)
{
IMMTLSDATA *pData;
TRACE("()\n");
pData = Imm32GetTLS();
if (pData)
++(pData->bDoCount);
}
/***********************************************************************
* CtfImmLeaveCoInitCountSkipMode (IMM32.@)
*/
BOOL WINAPI CtfImmLeaveCoInitCountSkipMode(VOID)
{
IMMTLSDATA *pData;
TRACE("()\n");
pData = Imm32GetTLS();
if (!pData || !pData->bDoCount)
return FALSE;
--(pData->bDoCount);
return TRUE;
}
/***********************************************************************
* ISPY (I am not spy!)
*
* ISPY watches CoInitialize[Ex] / CoUninitialize to manage COM initialization status.
*/
typedef struct ISPY
{
const IInitializeSpyVtbl *m_pSpyVtbl;
LONG m_cRefs;
} ISPY, *PISPY;
static STDMETHODIMP
ISPY_QueryInterface(
_Inout_ IInitializeSpy *pThis,
_In_ REFIID riid,
_Inout_ LPVOID *ppvObj)
{
ISPY *pSpy = (ISPY*)pThis;
if (!ppvObj)
return E_INVALIDARG;
*ppvObj = NULL;
if (!IsEqualIID(riid, &IID_IUnknown) && !IsEqualIID(riid, &IID_IInitializeSpy))
return E_NOINTERFACE;
++(pSpy->m_cRefs);
*ppvObj = pSpy;
return S_OK;
}
static STDMETHODIMP_(ULONG)
ISPY_AddRef(
_Inout_ IInitializeSpy *pThis)
{
ISPY *pSpy = (ISPY*)pThis;
return ++pSpy->m_cRefs;
}
static STDMETHODIMP_(ULONG)
ISPY_Release(
_Inout_ IInitializeSpy *pThis)
{
ISPY *pSpy = (ISPY*)pThis;
if (--pSpy->m_cRefs == 0)
{
ImmLocalFree(pSpy);
return 0;
}
return pSpy->m_cRefs;
}
/*
* (Pre/Post)(Initialize/Uninitialize) will be automatically called from OLE32
* as the results of watching.
*/
static STDMETHODIMP
ISPY_PreInitialize(
_Inout_ IInitializeSpy *pThis,
_In_ DWORD dwCoInit,
_In_ DWORD dwCurThreadAptRefs)
{
DWORD cCount;
UNREFERENCED_PARAMETER(pThis);
cCount = Imm32IncCoInitCountSkip();
if (!dwCoInit &&
(dwCurThreadAptRefs == cCount + 1) &&
(GetWin32ClientInfo()->CI_flags & CI_CTFCOINIT))
{
Imm32ActivateOrDeactivateTIM(FALSE);
CtfImmCoUninitialize();
}
return S_OK;
}
static STDMETHODIMP
ISPY_PostInitialize(
_Inout_ IInitializeSpy *pThis,
_In_ HRESULT hrCoInit,
_In_ DWORD dwCoInit,
_In_ DWORD dwNewThreadAptRefs)
{
DWORD CoInitCountSkip;
UNREFERENCED_PARAMETER(pThis);
UNREFERENCED_PARAMETER(dwCoInit);
CoInitCountSkip = Imm32GetCoInitCountSkip();
if ((hrCoInit != S_FALSE) ||
(dwNewThreadAptRefs != CoInitCountSkip + 2) ||
!(GetWin32ClientInfo()->CI_flags & CI_CTFCOINIT))
{
return hrCoInit;
}
return S_OK;
}
static STDMETHODIMP
ISPY_PreUninitialize(
_Inout_ IInitializeSpy *pThis,
_In_ DWORD dwCurThreadAptRefs)
{
UNREFERENCED_PARAMETER(pThis);
if (dwCurThreadAptRefs == 1 &&
!RtlDllShutdownInProgress() &&
!Imm32InsideLoaderLock() &&
(GetWin32ClientInfo()->CI_flags & CI_CTFCOINIT))
{
IMMTLSDATA *pData = Imm32GetTLS();
if (pData && !pData->bUninitializing)
Imm32CoInitializeEx();
}
return S_OK;
}
static STDMETHODIMP
ISPY_PostUninitialize(
_In_ IInitializeSpy *pThis,
_In_ DWORD dwNewThreadAptRefs)
{
UNREFERENCED_PARAMETER(pThis);
UNREFERENCED_PARAMETER(dwNewThreadAptRefs);
Imm32DecCoInitCountSkip();
return S_OK;
}
static const IInitializeSpyVtbl g_vtblISPY =
{
ISPY_QueryInterface,
ISPY_AddRef,
ISPY_Release,
ISPY_PreInitialize,
ISPY_PostInitialize,
ISPY_PreUninitialize,
ISPY_PostUninitialize,
};
static ISPY*
Imm32AllocIMMISPY(VOID)
{
ISPY *pSpy = (ISPY*)ImmLocalAlloc(0, sizeof(ISPY));
if (!pSpy)
return NULL;
pSpy->m_pSpyVtbl = &g_vtblISPY;
pSpy->m_cRefs = 1;
return pSpy;
}
#define Imm32DeleteIMMISPY(pSpy) ImmLocalFree(pSpy)
/***********************************************************************
* CtfImmCoInitialize (Not exported)
*/
HRESULT
CtfImmCoInitialize(VOID)
{
HRESULT hr;
IMMTLSDATA *pData;
ISPY *pSpy;
if (GetWin32ClientInfo()->CI_flags & CI_CTFCOINIT)
return S_OK; /* Already initialized */
hr = Imm32CoInitializeEx();
if (FAILED_UNEXPECTEDLY(hr))
return hr; /* CoInitializeEx failed */
GetWin32ClientInfo()->CI_flags |= CI_CTFCOINIT;
Imm32InitTLS();
pData = Imm32AllocateTLS();
if (!pData || pData->pSpy)
return S_OK; /* Cannot allocate or already it has a spy */
pSpy = Imm32AllocIMMISPY();
pData->pSpy = (IInitializeSpy*)pSpy;
if (IS_NULL_UNEXPECTEDLY(pSpy))
return S_OK; /* Cannot allocate a spy */
if (FAILED_UNEXPECTEDLY(Imm32CoRegisterInitializeSpy(pData->pSpy, &pData->uliCookie)))
{
/* Failed to register the spy */
Imm32DeleteIMMISPY(pData->pSpy);
pData->pSpy = NULL;
pData->uliCookie.QuadPart = 0;
}
return S_OK;
}
/***********************************************************************
* CtfImmCoUninitialize (IMM32.@)
*/
VOID WINAPI
CtfImmCoUninitialize(VOID)
{
IMMTLSDATA *pData;
if (!(GetWin32ClientInfo()->CI_flags & CI_CTFCOINIT))
return; /* Not CoInitialize'd */
pData = Imm32GetTLS();
if (pData)
{
pData->bUninitializing = TRUE;
Imm32CoUninitialize(); /* Do CoUninitialize */
pData->bUninitializing = FALSE;
GetWin32ClientInfo()->CI_flags &= ~CI_CTFCOINIT;
}
pData = Imm32AllocateTLS();
if (!pData || !pData->pSpy)
return; /* There were no spy */
/* Our work is done. We don't need spies like you anymore. */
Imm32CoRevokeInitializeSpy(pData->uliCookie);
ISPY_Release(pData->pSpy);
pData->pSpy = NULL;
pData->uliCookie.QuadPart = 0;
}
/***********************************************************************
* This function loads the CTF IME file if necessary and establishes
* communication with the CTF IME.
@ -286,6 +743,8 @@ Imm32LoadCtfIme(VOID)
HRESULT
CtfImeCreateThreadMgr(VOID)
{
TRACE("()\n");
if (!Imm32LoadCtfIme())
return E_FAIL;
@ -298,6 +757,8 @@ CtfImeCreateThreadMgr(VOID)
HRESULT
CtfImeDestroyThreadMgr(VOID)
{
TRACE("()\n");
if (!Imm32LoadCtfIme())
return E_FAIL;
@ -362,6 +823,8 @@ HRESULT
CtfImeCreateInputContext(
_In_ HIMC hIMC)
{
TRACE("(%p)\n", hIMC);
if (!Imm32LoadCtfIme())
return E_FAIL;
@ -374,6 +837,8 @@ CtfImeCreateInputContext(
HRESULT
CtfImeDestroyInputContext(_In_ HIMC hIMC)
{
TRACE("(%p)\n", hIMC);
if (!Imm32LoadCtfIme())
return E_FAIL;
@ -394,8 +859,61 @@ Imm32EnumCreateCtfICProc(
}
/***********************************************************************
* This function calls CtfImeDestroyInputContext if possible.
* Thread Input Manager (TIM)
*/
static BOOL
Imm32IsTIMDisabledInRegistry(VOID)
{
DWORD dwData, cbData;
HKEY hKey;
LSTATUS error;
error = RegOpenKeyW(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\CTF", &hKey);
if (error != ERROR_SUCCESS)
return FALSE;
dwData = 0;
cbData = sizeof(dwData);
RegQueryValueExW(hKey, L"Disable Thread Input Manager", NULL, NULL, (LPBYTE)&dwData, &cbData);
RegCloseKey(hKey);
return !!dwData;
}
HRESULT
Imm32ActivateOrDeactivateTIM(
_In_ BOOL bCreate)
{
HRESULT hr = S_OK;
if (!IS_CICERO_MODE() || IS_16BIT_MODE() ||
!(GetWin32ClientInfo()->CI_flags & CI_CTFCOINIT))
{
return S_OK; /* No need to activate/de-activate TIM */
}
if (bCreate)
{
if (!(GetWin32ClientInfo()->CI_flags & CI_CTFTIM))
{
hr = CtfImeCreateThreadMgr();
if (SUCCEEDED(hr))
GetWin32ClientInfo()->CI_flags |= CI_CTFTIM;
}
}
else /* Destroy */
{
if (GetWin32ClientInfo()->CI_flags & CI_CTFTIM)
{
hr = CtfImeDestroyThreadMgr();
if (SUCCEEDED(hr))
GetWin32ClientInfo()->CI_flags &= ~CI_CTFTIM;
}
}
return hr;
}
HRESULT
CtfImmTIMDestroyInputContext(
_In_ HIMC hIMC)
@ -422,34 +940,34 @@ CtfImmTIMCreateInputContext(
if (GetWin32ClientInfo()->CI_flags & CI_AIMMACTIVATED)
{
if (!pClientImc->bUnknown4)
if (!pClientImc->bCtfIme)
{
dwImeThreadId = NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID);
dwCurrentThreadId = GetCurrentThreadId();
if (dwImeThreadId == dwCurrentThreadId)
{
pClientImc->bUnknown4 = 1;
pClientImc->bCtfIme = TRUE;
hr = CtfImeCreateInputContext(hIMC);
if (FAILED(hr))
pClientImc->bUnknown4 = 0;
if (FAILED_UNEXPECTEDLY(hr))
pClientImc->bCtfIme = FALSE;
}
}
}
else
{
if (!(GetWin32ClientInfo()->CI_flags & 0x100))
if (!(GetWin32ClientInfo()->CI_flags & CI_CTFTIM))
return S_OK;
if (!pClientImc->bUnknown4)
if (!pClientImc->bCtfIme)
{
dwImeThreadId = NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID);
dwCurrentThreadId = GetCurrentThreadId();
if ((dwImeThreadId == dwCurrentThreadId) && IS_CICERO_MODE() && !IS_16BIT_MODE())
{
pClientImc->bUnknown4 = 1;
pClientImc->bCtfIme = TRUE;
hr = CtfImeCreateInputContext(hIMC);
if (FAILED(hr))
pClientImc->bUnknown4 = 0;
if (FAILED_UNEXPECTEDLY(hr))
pClientImc->bCtfIme = FALSE;
}
}
}
@ -458,6 +976,19 @@ CtfImmTIMCreateInputContext(
return hr;
}
/***********************************************************************
* CtfImmLastEnabledWndDestroy (IMM32.@)
*
* Same as Imm32ActivateOrDeactivateTIM but its naming is improper.
*/
HRESULT WINAPI
CtfImmLastEnabledWndDestroy(
_In_ BOOL bCreate)
{
TRACE("(%d)\n", bCreate);
return Imm32ActivateOrDeactivateTIM(bCreate);
}
/***********************************************************************
* CtfAImmActivate (IMM32.@)
*
@ -529,7 +1060,7 @@ CtfImmIsCiceroEnabled(VOID)
}
/***********************************************************************
* CtfImmIsTextFrameServiceDisabled(IMM32.@)
* CtfImmIsTextFrameServiceDisabled (IMM32.@)
*
* @return TRUE if TSF is disabled.
*/
@ -540,17 +1071,123 @@ CtfImmIsTextFrameServiceDisabled(VOID)
}
/***********************************************************************
* CtfImmTIMActivate(IMM32.@)
* ImmDisableTextFrameService (IMM32.@)
*/
BOOL WINAPI
ImmDisableTextFrameService(_In_ DWORD dwThreadId)
{
HRESULT hr = S_OK;
TRACE("(0x%lX)\n", dwThreadId);
if (dwThreadId == -1)
g_disable_CUAS_flag = TRUE;
if ((dwThreadId && !g_disable_CUAS_flag) || (GetWin32ClientInfo()->CI_flags & CI_TSFDISABLED))
return TRUE;
GetWin32ClientInfo()->CI_flags |= CI_TSFDISABLED;
if (IS_CICERO_MODE() && !IS_16BIT_MODE() &&
(GetWin32ClientInfo()->CI_flags & CI_CTFCOINIT) &&
(GetWin32ClientInfo()->CI_flags & CI_CTFTIM))
{
hr = CtfImeDestroyThreadMgr();
if (SUCCEEDED(hr))
{
GetWin32ClientInfo()->CI_flags &= ~CI_CTFTIM;
CtfImmCoUninitialize();
}
}
return hr == S_OK;
}
/***********************************************************************
* CtfImmTIMActivate (IMM32.@)
*
* Activates Thread Input Manager (TIM) in the thread.
*/
HRESULT WINAPI
CtfImmTIMActivate(_In_ HKL hKL)
{
FIXME("(%p)\n", hKL);
return E_NOTIMPL;
HRESULT hr = S_OK;
TRACE("(%p)\n", hKL);
if (g_disable_CUAS_flag)
{
TRACE("g_disable_CUAS_flag\n");
GetWin32ClientInfo()->CI_flags |= CI_TSFDISABLED;
return FALSE;
}
if (GetWin32ClientInfo()->CI_flags & CI_TSFDISABLED)
{
TRACE("CI_TSFDISABLED\n");
return FALSE;
}
if (Imm32IsTIMDisabledInRegistry())
{
TRACE("TIM is disabled in registry\n");
GetWin32ClientInfo()->CI_flags |= CI_TSFDISABLED;
return FALSE;
}
if (!Imm32IsInteractiveUserLogon() || Imm32IsRunningInMsoobe())
{
TRACE("TIM is disabled due to LOGON or MSOBE\n");
return FALSE;
}
if (!Imm32IsCUASEnabledInRegistry())
{
TRACE("CUAS is disabled in registry\n");
GetWin32ClientInfo()->CI_flags |= CI_TSFDISABLED;
return FALSE;
}
if (NtCurrentTeb()->ProcessEnvironmentBlock->AppCompatFlags.LowPart & 0x100)
{
TRACE("CUAS is disabled by AppCompatFlags\n");
GetWin32ClientInfo()->CI_flags |= CI_TSFDISABLED;
return FALSE;
}
if (RtlIsThreadWithinLoaderCallout() || Imm32InsideLoaderLock())
{
TRACE("TIM is disabled by Loader\n");
return FALSE;
}
if (!IS_CICERO_MODE() || IS_16BIT_MODE())
{
TRACE("TIM is disabled because CICERO mode is unset\n");
return FALSE;
}
if (IS_IME_HKL(hKL))
hKL = (HKL)UlongToHandle(MAKELONG(LOWORD(hKL), LOWORD(hKL)));
if (!ImmLoadIME(hKL))
Imm32TF_InvalidAssemblyListCacheIfExist();
CtfImmCoInitialize();
if ((GetWin32ClientInfo()->CI_flags & CI_CTFCOINIT) &&
!(GetWin32ClientInfo()->CI_flags & CI_CTFTIM))
{
hr = CtfImeCreateThreadMgr();
if (SUCCEEDED(hr))
GetWin32ClientInfo()->CI_flags |= CI_CTFTIM;
}
return hr;
}
/***********************************************************************
* CtfImmGenerateMessage(IMM32.@)
* CtfImmGenerateMessage (IMM32.@)
*/
BOOL WINAPI
CtfImmGenerateMessage(
@ -638,7 +1275,7 @@ CtfImmGenerateMessage(
}
/***********************************************************************
* CtfImmHideToolbarWnd(IMM32.@)
* CtfImmHideToolbarWnd (IMM32.@)
*
* Used with CtfImmRestoreToolbarWnd.
*/
@ -667,7 +1304,7 @@ CtfImmHideToolbarWnd(VOID)
}
/***********************************************************************
* CtfImmRestoreToolbarWnd(IMM32.@)
* CtfImmRestoreToolbarWnd (IMM32.@)
*
* Used with CtfImmHideToolbarWnd.
*/
@ -684,7 +1321,7 @@ CtfImmRestoreToolbarWnd(
TRACE("(%p, 0x%X)\n", pUnused, dwShowFlags);
hr = Imm32TF_CreateLangBarMgr(&pBarMgr);
if (FAILED(hr))
if (FAILED_UNEXPECTEDLY(hr))
return;
if (dwShowFlags)
@ -693,20 +1330,8 @@ CtfImmRestoreToolbarWnd(
pBarMgr->lpVtbl->Release(pBarMgr);
}
BOOL Imm32InsideLoaderLock(VOID)
{
return (NtCurrentTeb()->ProcessEnvironmentBlock->LoaderLock->OwningThread ==
NtCurrentTeb()->ClientId.UniqueThread);
}
/* FIXME: Use RTL */
BOOL WINAPI RtlDllShutdownInProgress(VOID)
{
return FALSE;
}
/***********************************************************************
* CtfImmDispatchDefImeMessage(IMM32.@)
* CtfImmDispatchDefImeMessage (IMM32.@)
*/
LRESULT WINAPI
CtfImmDispatchDefImeMessage(
@ -724,7 +1349,7 @@ CtfImmDispatchDefImeMessage(
}
/***********************************************************************
* CtfImmIsGuidMapEnable(IMM32.@)
* CtfImmIsGuidMapEnable (IMM32.@)
*/
BOOL WINAPI
CtfImmIsGuidMapEnable(
@ -757,7 +1382,7 @@ CtfImmIsGuidMapEnable(
}
/***********************************************************************
* CtfImmGetGuidAtom(IMM32.@)
* CtfImmGetGuidAtom (IMM32.@)
*/
HRESULT WINAPI
CtfImmGetGuidAtom(

View file

@ -1103,15 +1103,6 @@ BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
return TRUE; // Do nothing. This is correct.
}
/***********************************************************************
* ImmDisableTextFrameService(IMM32.@)
*/
BOOL WINAPI ImmDisableTextFrameService(DWORD dwThreadId)
{
FIXME("Stub\n");
return FALSE;
}
/***********************************************************************
* ImmEnumInputContext(IMM32.@)
*/

View file

@ -1,7 +1,9 @@
@ stdcall CtfAImmActivate(ptr)
@ stdcall CtfAImmDeactivate(long)
@ stdcall CtfAImmIsIME(ptr)
@ stdcall CtfImmCoUninitialize()
@ stdcall CtfImmDispatchDefImeMessage(ptr long ptr ptr)
@ stdcall CtfImmEnterCoInitCountSkipMode()
@ stdcall CtfImmGenerateMessage(ptr long)
@ stdcall CtfImmGetGuidAtom(ptr long ptr)
@ stdcall CtfImmHideToolbarWnd()
@ -9,6 +11,8 @@
@ stdcall CtfImmIsCiceroStartedInThread()
@ stdcall CtfImmIsGuidMapEnable(ptr)
@ stdcall CtfImmIsTextFrameServiceDisabled()
@ stdcall CtfImmLastEnabledWndDestroy(long)
@ stdcall CtfImmLeaveCoInitCountSkipMode()
@ stdcall CtfImmRestoreToolbarWnd(ptr long)
@ stdcall CtfImmSetAppCompatFlags(long)
@ stdcall CtfImmSetCiceroStartInThread(long)

View file

@ -112,12 +112,17 @@ BOOL WINAPI Imm32IsImcAnsi(HIMC hIMC);
* --- Examine the condition, and then generate trace log if necessary.
*/
#ifdef NDEBUG /* on Release */
#define FAILED_UNEXPECTEDLY(hr) (FAILED(hr))
#define IS_NULL_UNEXPECTEDLY(p) (!(p))
#define IS_ZERO_UNEXPECTEDLY(p) (!(p))
#define IS_TRUE_UNEXPECTEDLY(x) (x)
#define IS_FALSE_UNEXPECTEDLY(x) (!(x))
#define IS_ERROR_UNEXPECTEDLY(x) (!(x))
#else /* on Debug */
#define FAILED_UNEXPECTEDLY(hr) \
(FAILED(hr) ? (ros_dbg_log(__WINE_DBCL_ERR, __wine_dbch___default, \
__FILE__, __FUNCTION__, __LINE__, "FAILED(%s)\n", #hr), UNEXPECTED(), TRUE) \
: FALSE)
#define IS_NULL_UNEXPECTEDLY(p) \
(!(p) ? (ros_dbg_log(__WINE_DBCL_ERR, __wine_dbch___default, \
__FILE__, __FUNCTION__, __LINE__, "%s was NULL\n", #p), UNEXPECTED(), TRUE) \
@ -192,3 +197,7 @@ BOOL Imm32StoreBitmapToBytes(HBITMAP hbm, LPBYTE pbData, DWORD cbDataMax);
HRESULT CtfImmTIMCreateInputContext(_In_ HIMC hIMC);
HRESULT CtfImmTIMDestroyInputContext(_In_ HIMC hIMC);
HRESULT CtfImmCoInitialize(VOID);
HRESULT CtfImeCreateThreadMgr(VOID);
HRESULT CtfImeDestroyThreadMgr(VOID);
HRESULT Imm32ActivateOrDeactivateTIM(_In_ BOOL bCreate);

View file

@ -17,6 +17,8 @@
extern "C" {
#endif
BOOL WINAPI ImmDisableTextFrameService(_In_ DWORD dwThreadId);
typedef struct tagSOFTKBDDATA
{
UINT uCount;
@ -317,7 +319,7 @@ typedef struct tagCLIENTIMC
RTL_CRITICAL_SECTION cs;
UINT uCodePage;
HKL hKL;
BOOL bUnknown4;
BOOL bCtfIme;
} CLIENTIMC, *PCLIENTIMC;
#ifndef _WIN64

View file

@ -31,6 +31,10 @@ VOID WINAPI CtfImmSetAppCompatFlags(_In_ DWORD dwFlags);
DWORD WINAPI CtfImmHideToolbarWnd(VOID);
VOID WINAPI CtfImmRestoreToolbarWnd(_In_ LPVOID pUnused, _In_ DWORD dwShowFlags);
BOOL WINAPI CtfImmGenerateMessage(_In_ HIMC hIMC, _In_ BOOL bSend);
VOID WINAPI CtfImmCoUninitialize(VOID);
VOID WINAPI CtfImmEnterCoInitCountSkipMode(VOID);
BOOL WINAPI CtfImmLeaveCoInitCountSkipMode(VOID);
HRESULT WINAPI CtfImmLastEnabledWndDestroy(_In_ BOOL bCreate);
LRESULT WINAPI
CtfImmDispatchDefImeMessage(

View file

@ -303,6 +303,8 @@ typedef struct _CALLBACKWND
#define CI_CURTHPRHOOK 0x00000010
#define CI_CLASSESREGISTERED 0x00000020
#define CI_IMMACTIVATE 0x00000040 /* IMM/IME (Asian input) */
#define CI_CTFCOINIT 0x00000080 /* Did CTF CoInitialize? */
#define CI_CTFTIM 0x00000100 /* CTF Thread Input Manager (TIM) */
#define CI_TSFDISABLED 0x00000400 /* TSF (Text Services Framework a.k.a. Cicero) */
#define CI_AIMMACTIVATED 0x00000800 /* Active IMM (AIMM) */