From c876fe350d5d907a1492389c0d6f1fa5a6961b00 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Tue, 20 May 2025 07:34:46 +0900 Subject: [PATCH] [IMM32][NTUSER] Strictly check Cicero IME (#8009) This PR enhances Cicero IME support. JIRA issue: CORE-19268 - Add null checks for the functions of Cicero IMEs in Imm32LoadIME function. - Add and use IS_CICERO_COMPAT_DISABLED macro in win32ss/include/ntuser.h. - Fix ImmGetImeInfoEx, Imm32LoadImeDpi, ImmGetDescriptionA, ImmGetDescriptionW, ImmGetIMEFileNameA, ImmGetIMEFileNameW, and ImmGetProperty functions for Cicero IME support. - Set last error in NtUserGetImeInfoEx. --- dll/win32/imm32/ctf.c | 2 +- dll/win32/imm32/ime.c | 118 ++++++++++++++------------------------ win32ss/include/ntuser.h | 5 ++ win32ss/user/ntuser/ime.c | 12 +++- 4 files changed, 58 insertions(+), 79 deletions(-) diff --git a/dll/win32/imm32/ctf.c b/dll/win32/imm32/ctf.c index 5a3cb81d9b5..1d5349f61e7 100644 --- a/dll/win32/imm32/ctf.c +++ b/dll/win32/imm32/ctf.c @@ -929,7 +929,7 @@ HRESULT CtfImmTIMDestroyInputContext( _In_ HIMC hIMC) { - if (!IS_CICERO_MODE() || (GetWin32ClientInfo()->dwCompatFlags2 & 2)) + if (!IS_CICERO_MODE() || IS_CICERO_COMPAT_DISABLED()) return E_NOINTERFACE; return CtfImeDestroyInputContext(hIMC); diff --git a/dll/win32/imm32/ime.c b/dll/win32/imm32/ime.c index 8ac47a85e7f..2eeadfd3631 100644 --- a/dll/win32/imm32/ime.c +++ b/dll/win32/imm32/ime.c @@ -6,7 +6,7 @@ * Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart * Copyright 2017 James Tabor * Copyright 2018 Amine Khaldi - * Copyright 2020-2022 Katayama Hirofumi MZ + * Copyright 2020-2025 Katayama Hirofumi MZ */ #include "precomp.h" @@ -194,7 +194,6 @@ BOOL APIENTRY Imm32InquireIme(PIMEDPI pImeDpi) #include #undef DEFINE_IME_ENTRY -// Win: LoadIME BOOL APIENTRY Imm32LoadIME(PIMEINFOEX pImeInfoEx, PIMEDPI pImeDpi) { WCHAR szPath[MAX_PATH]; @@ -230,6 +229,23 @@ BOOL APIENTRY Imm32LoadIME(PIMEINFOEX pImeInfoEx, PIMEDPI pImeDpi) #include #undef DEFINE_IME_ENTRY + /* Check for Cicero IMEs */ + if (!IS_IME_HKL(pImeDpi->hKL) && IS_CICERO_MODE() && !IS_CICERO_COMPAT_DISABLED()) + { +#define CHECK_IME_FN(name) do { \ + if (!pImeDpi->name) { \ + ERR("'%s' not found in Cicero IME module '%S'.\n", #name, szPath); \ + goto Failed; \ + } \ +} while(0) + CHECK_IME_FN(CtfImeInquireExW); + CHECK_IME_FN(CtfImeSelectEx); + CHECK_IME_FN(CtfImeEscapeEx); + CHECK_IME_FN(CtfImeGetGuidAtom); + CHECK_IME_FN(CtfImeIsGuidMapEnable); +#undef CHECK_IME_FN + } + if (Imm32InquireIme(pImeDpi)) { ret = TRUE; @@ -263,7 +279,6 @@ Failed: return ret; } -// Win: LoadImeDpi PIMEDPI APIENTRY Imm32LoadImeDpi(HKL hKL, BOOL bLock) { IMEINFOEX ImeInfoEx; @@ -272,12 +287,6 @@ PIMEDPI APIENTRY Imm32LoadImeDpi(HKL hKL, BOOL bLock) UINT uCodePage; LCID lcid; - if (!IS_IME_HKL(hKL)) - { - TRACE("\n"); - return NULL; - } - if (!ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExKeyboardLayout, &hKL)) { ERR("\n"); @@ -608,45 +617,38 @@ BOOL WINAPI ImmNotifyIME(HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD_PTR dwV BOOL WINAPI ImmGetImeInfoEx(PIMEINFOEX pImeInfoEx, IMEINFOEXCLASS SearchType, PVOID pvSearchKey) { - HKL hKL; - if (SearchType == ImeInfoExKeyboardLayout || SearchType == ImeInfoExKeyboardLayoutTFS) + BOOL bTextServiceDisabled = FALSE; + + if (SearchType == ImeInfoExKeyboardLayoutTFS) { - hKL = *(HKL*)pvSearchKey; + SearchType = ImeInfoExKeyboardLayout; + bTextServiceDisabled = CtfImmIsTextFrameServiceDisabled(); + } + + if (SearchType == ImeInfoExKeyboardLayout) + { + HKL hKL = *(HKL *)pvSearchKey; pImeInfoEx->hkl = hKL; - if (SearchType == ImeInfoExKeyboardLayoutTFS) + if (!IS_IME_HKL(hKL) && + (!IS_CICERO_MODE() || IS_CICERO_COMPAT_DISABLED() || bTextServiceDisabled)) { - if (!IS_IME_HKL(hKL)) - { - if (CtfImmIsTextFrameServiceDisabled() || !IS_CICERO_MODE() || IS_16BIT_MODE()) - { - TRACE("\n"); - return FALSE; - } - } + TRACE("IME is disabled\n"); + return FALSE; + } - SearchType = ImeInfoExKeyboardLayout; - } - else - { - if (!IS_IME_HKL(hKL)) - { - TRACE("\n"); - return FALSE; - } - } - } - else if (SearchType == ImeInfoExImeFileName) - { - StringCchCopyW(pImeInfoEx->wszImeFile, _countof(pImeInfoEx->wszImeFile), - pvSearchKey); - } - else - { - return FALSE; + return NtUserGetImeInfoEx(pImeInfoEx, SearchType); } - return NtUserGetImeInfoEx(pImeInfoEx, SearchType); + if (SearchType == ImeInfoExImeFileName) + { + StringCchCopyW(pImeInfoEx->wszImeFile, _countof(pImeInfoEx->wszImeFile), pvSearchKey); + return NtUserGetImeInfoEx(pImeInfoEx, SearchType); + } + + /* NOTE: ImeInfoExImeWindow is ignored */ + ERR("SearchType: %d\n", SearchType); + return FALSE; } /*********************************************************************** @@ -763,12 +765,6 @@ UINT WINAPI ImmGetDescriptionA(HKL hKL, LPSTR lpszDescription, UINT uBufLen) TRACE("(%p,%p,%d)\n", hKL, lpszDescription, uBufLen); - if (!IS_IME_HKL(hKL)) - { - TRACE("\n"); - return 0; - } - if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL)) { ERR("\n"); @@ -793,12 +789,6 @@ UINT WINAPI ImmGetDescriptionW(HKL hKL, LPWSTR lpszDescription, UINT uBufLen) TRACE("(%p, %p, %d)\n", hKL, lpszDescription, uBufLen); - if (!IS_IME_HKL(hKL)) - { - TRACE("\n"); - return 0; - } - if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL)) { ERR("\n"); @@ -823,14 +813,6 @@ UINT WINAPI ImmGetIMEFileNameA( HKL hKL, LPSTR lpszFileName, UINT uBufLen) TRACE("(%p, %p, %u)\n", hKL, lpszFileName, uBufLen); - if (!IS_IME_HKL(hKL)) - { - TRACE("\n"); - if (uBufLen > 0) - lpszFileName[0] = 0; - return 0; - } - if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL)) { ERR("\n"); @@ -863,14 +845,6 @@ UINT WINAPI ImmGetIMEFileNameW(HKL hKL, LPWSTR lpszFileName, UINT uBufLen) TRACE("(%p, %p, %u)\n", hKL, lpszFileName, uBufLen); - if (!IS_IME_HKL(hKL)) - { - TRACE("\n"); - if (uBufLen > 0) - lpszFileName[0] = 0; - return 0; - } - if (!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayout, &hKL)) { ERR("\n"); @@ -904,12 +878,6 @@ DWORD WINAPI ImmGetProperty(HKL hKL, DWORD fdwIndex) TRACE("(%p, %lu)\n", hKL, fdwIndex); - if (!IS_IME_HKL(hKL)) - { - TRACE("\n"); - return FALSE; - } - if (!ImmGetImeInfoEx(&ImeInfoEx, ImeInfoExKeyboardLayout, &hKL)) { ERR("\n"); diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h index fab334c37f2..451dcb03635 100644 --- a/win32ss/include/ntuser.h +++ b/win32ss/include/ntuser.h @@ -1206,9 +1206,14 @@ typedef struct tagCURSORDATA #define CURSORF_LINKED 0x0100 #define CURSORF_CURRENT 0x0200 +/* Flags for dwCompatFlags2 */ +#define COMPAT_FLAG_2_CICERO_DISABLED 2 + #define IS_IMM_MODE() (gpsi && (gpsi->dwSRVIFlags & SRVINFO_IMM32)) #define IS_CICERO_MODE() (gpsi && (gpsi->dwSRVIFlags & SRVINFO_CICERO_ENABLED)) #define IS_16BIT_MODE() (GetWin32ClientInfo()->dwTIFlags & TIF_16BIT) +#define IS_CICERO_COMPAT_DISABLED() \ + (GetWin32ClientInfo()->dwCompatFlags2 & COMPAT_FLAG_2_CICERO_DISABLED) typedef struct tagIMEUI { diff --git a/win32ss/user/ntuser/ime.c b/win32ss/user/ntuser/ime.c index 2daa28f3f40..70d2b29e5fc 100644 --- a/win32ss/user/ntuser/ime.c +++ b/win32ss/user/ntuser/ime.c @@ -946,7 +946,6 @@ Quit: return ret; } -// Win: GetImeInfoEx BOOL FASTCALL UserGetImeInfoEx( _Inout_ PWINSTATION_OBJECT pWinSta, @@ -1006,8 +1005,8 @@ UserGetImeInfoEx( BOOL NTAPI NtUserGetImeInfoEx( - PIMEINFOEX pImeInfoEx, - IMEINFOEXCLASS SearchType) + _Inout_ PIMEINFOEX pImeInfoEx, + _In_ IMEINFOEXCLASS SearchType) { IMEINFOEX ImeInfoEx; BOOL ret = FALSE; @@ -1018,6 +1017,7 @@ NtUserGetImeInfoEx( if (!IS_IMM_MODE()) { ERR("!IS_IMM_MODE()\n"); + EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED); goto Quit; } @@ -1824,6 +1824,12 @@ NtUserQueryInputContext(HIMC hIMC, DWORD dwType) if (ptiIMC->spDefaultImc) ret = (DWORD_PTR)UserHMGetHandle(ptiIMC->spDefaultImc); break; + + default: + { + FIXME("dwType: %ld\n", dwType); + break; + } } Quit: