[NTUSER][IMM32] Implement NtUserGetImeInfoEx (#4271)

- Add UserGetImeInfoEx helper function.
- Implement NtUserGetImeInfoEx function by using UserGetImeInfoEx.
- Fix imm32.ImmGetImeInfoEx.
- Modify enum IMEINFOEXCLASS.
CORE-11700
This commit is contained in:
Katayama Hirofumi MZ 2022-01-12 12:06:24 +09:00 committed by GitHub
parent a47590c9cf
commit 36740ca981
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 118 additions and 36 deletions

View file

@ -574,8 +574,7 @@ HKL WINAPI ImmInstallIMEW(LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
}
/* If the IME for the specified filename is valid, then unload it now */
/* FIXME: ImmGetImeInfoEx is broken */
if (ImmGetImeInfoEx(&InfoEx, 3, pchFilePart) &&
if (ImmGetImeInfoEx(&InfoEx, ImeInfoExImeFileName, pchFilePart) &&
!UnloadKeyboardLayout(InfoEx.hkl))
{
hNewKL = NULL;
@ -623,8 +622,7 @@ BOOL WINAPI ImmIsIME(HKL hKL)
{
IMEINFOEX info;
TRACE("(%p)\n", hKL);
/* FIXME: ImmGetImeInfoEx is broken */
return !!ImmGetImeInfoEx(&info, 1, &hKL);
return !!ImmGetImeInfoEx(&info, ImeInfoExKeyboardLayoutTFS, &hKL);
}
/***********************************************************************
@ -681,42 +679,41 @@ BOOL WINAPI ImmDisableLegacyIME(void)
BOOL WINAPI
ImmGetImeInfoEx(PIMEINFOEX pImeInfoEx, IMEINFOEXCLASS SearchType, PVOID pvSearchKey)
{
BOOL bDisabled = FALSE;
HKL hKL;
/* FIXME: broken */
switch (SearchType)
if (SearchType == ImeInfoExKeyboardLayout || SearchType == ImeInfoExKeyboardLayoutTFS)
{
case ImeInfoExKeyboardLayout:
break;
hKL = *(HKL*)pvSearchKey;
pImeInfoEx->hkl = hKL;
case ImeInfoExImeWindow:
bDisabled = CtfImmIsTextFrameServiceDisabled();
SearchType = ImeInfoExKeyboardLayout;
break;
case ImeInfoExImeFileName:
StringCchCopyW(pImeInfoEx->wszImeFile, _countof(pImeInfoEx->wszImeFile),
pvSearchKey);
goto Quit;
}
hKL = *(HKL*)pvSearchKey;
pImeInfoEx->hkl = hKL;
if (!IS_IME_HKL(hKL))
{
if (Imm32IsCiceroMode())
if (SearchType == ImeInfoExKeyboardLayoutTFS)
{
if (Imm32Is16BitMode())
return FALSE;
if (!bDisabled)
goto Quit;
if (!IS_IME_HKL(hKL))
{
if (!CtfImmIsTextFrameServiceDisabled() ||
!Imm32IsCiceroMode() || Imm32Is16BitMode())
{
return FALSE;
}
}
SearchType = ImeInfoExKeyboardLayout;
}
else
{
if (!IS_IME_HKL(hKL))
return FALSE;
}
}
else if (SearchType == ImeInfoExImeFileName)
{
StringCchCopyW(pImeInfoEx->wszImeFile, _countof(pImeInfoEx->wszImeFile),
pvSearchKey);
}
else
{
return FALSE;
}
Quit:
return NtUserGetImeInfoEx(pImeInfoEx, SearchType);
}

View file

@ -1183,9 +1183,12 @@ typedef struct tagIMEINFOEX
};
} IMEINFOEX, *PIMEINFOEX;
typedef enum IMEINFOEXCLASS /* unconfirmed: buggy */
typedef enum IMEINFOEXCLASS
{
ImeInfoExKeyboardLayout,
#if 1
ImeInfoExKeyboardLayoutTFS,
#endif
ImeInfoExImeWindow,
ImeInfoExImeFileName
} IMEINFOEXCLASS;

View file

@ -157,16 +157,98 @@ NtUserGetAppImeLevel(HWND hWnd)
return 0;
}
BOOL FASTCALL UserGetImeInfoEx(LPVOID pUnknown, PIMEINFOEX pInfoEx, IMEINFOEXCLASS SearchType)
{
PKL pkl, pklHead;
if (!gspklBaseLayout)
return FALSE;
pkl = pklHead = gspklBaseLayout;
/* Find the matching entry from the list and get info */
if (SearchType == ImeInfoExKeyboardLayout)
{
do
{
if (pInfoEx->hkl == pkl->hkl) /* Matched */
{
if (!pkl->piiex)
break;
*pInfoEx = *pkl->piiex; /* Get */
return TRUE; /* Found */
}
pkl = pkl->pklNext;
} while (pkl != pklHead);
}
else if (SearchType == ImeInfoExImeFileName)
{
do
{
if (pkl->piiex &&
_wcsnicmp(pkl->piiex->wszImeFile, pInfoEx->wszImeFile,
RTL_NUMBER_OF(pkl->piiex->wszImeFile)) == 0) /* Matched */
{
*pInfoEx = *pkl->piiex; /* Get */
return TRUE; /* Found */
}
pkl = pkl->pklNext;
} while (pkl != pklHead);
}
else
{
/* Do nothing */
}
return FALSE; /* Not found */
}
BOOL
APIENTRY
NtUserGetImeInfoEx(
PIMEINFOEX pImeInfoEx,
IMEINFOEXCLASS SearchType)
{
STUB;
return FALSE;
}
IMEINFOEX ImeInfoEx;
BOOL ret = FALSE;
UserEnterShared();
if (!IS_IMM_MODE())
goto Quit;
_SEH2_TRY
{
ProbeForWrite(pImeInfoEx, sizeof(*pImeInfoEx), 1);
ImeInfoEx = *pImeInfoEx;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
goto Quit;
}
_SEH2_END;
ret = UserGetImeInfoEx(NULL, &ImeInfoEx, SearchType);
if (ret)
{
_SEH2_TRY
{
*pImeInfoEx = ImeInfoEx;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
ret = FALSE;
}
_SEH2_END;
}
Quit:
UserLeave();
return ret;
}
DWORD
APIENTRY