mirror of https://github.com/lianthony/NT4.0
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.
723 lines
18 KiB
723 lines
18 KiB
/**************************************************************************\
|
|
* Module Name: misc.c
|
|
*
|
|
* Copyright (c) Microsoft Corp. 1995 All Rights Reserved
|
|
*
|
|
*
|
|
* History:
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmGetDefaultIMEWnd
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
HWND WINAPI ImmGetDefaultIMEWnd(
|
|
HWND hWnd)
|
|
{
|
|
if (hWnd == NULL) {
|
|
/*
|
|
* Query default IME window of current thread.
|
|
*/
|
|
return (HWND)NtUserGetThreadState(UserThreadStateDefaultImeWindow);
|
|
}
|
|
|
|
return (HWND)NtUserQueryWindow(hWnd, WindowDefaultImeWindow);
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmIsUIMessageA
|
|
*
|
|
* Filter messages needed for IME window.
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
BOOL WINAPI ImmIsUIMessageA(
|
|
HWND hIMEWnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
return ImmIsUIMessageWorker(hIMEWnd, message, wParam, lParam, TRUE);
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmIsUIMessageW
|
|
*
|
|
* Filter messages needed for IME window.
|
|
*
|
|
* 29-Feb-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
BOOL WINAPI ImmIsUIMessageW(
|
|
HWND hIMEWnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam)
|
|
{
|
|
return ImmIsUIMessageWorker(hIMEWnd, message, wParam, lParam, FALSE);
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmIsUIMessageWorker
|
|
*
|
|
* Worker function of ImmIsUIMessageA/ImmIsUIMessageW.
|
|
*
|
|
* Return: True if message is processed by IME UI.
|
|
* False otherwise.
|
|
*
|
|
* 29-Feb-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
BOOL ImmIsUIMessageWorker(
|
|
HWND hIMEWnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
BOOL fAnsi)
|
|
{
|
|
switch (message) {
|
|
case WM_IME_STARTCOMPOSITION:
|
|
case WM_IME_ENDCOMPOSITION:
|
|
case WM_IME_COMPOSITION:
|
|
case WM_IME_SETCONTEXT:
|
|
case WM_IME_COMPOSITIONFULL:
|
|
case WM_IME_SELECT:
|
|
case WM_IME_NOTIFY:
|
|
case WM_IME_SYSTEM:
|
|
|
|
if (!hIMEWnd)
|
|
return TRUE;
|
|
|
|
#ifdef DEBUG
|
|
if (!IsWindow(hIMEWnd)) {
|
|
RIPMSG1(RIP_WARNING,
|
|
"ImmIsUIMessage: Invalid window handle %x", hIMEWnd);
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
|
|
if (fAnsi) {
|
|
SendMessageA(hIMEWnd, message, wParam, lParam);
|
|
}
|
|
else {
|
|
SendMessageW(hIMEWnd, message, wParam, lParam);
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmGenerateMessage
|
|
*
|
|
* Sends message(s) that are stored in hMsgBuf of hImc to hWnd of hImc.
|
|
*
|
|
* 29-Feb-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
BOOL WINAPI ImmGenerateMessage(
|
|
HIMC hImc)
|
|
{
|
|
PCLIENTIMC pClientImc;
|
|
PINPUTCONTEXT pInputContext;
|
|
LPDWORD lpdw;
|
|
INT iNum;
|
|
INT i;
|
|
BOOL fUnicodeImc;
|
|
|
|
if ((pClientImc = ImmLockClientImc(hImc)) == NULL)
|
|
return FALSE;
|
|
|
|
fUnicodeImc = TestICF(pClientImc, IMCF_UNICODE);
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
pInputContext = ImmLockIMC(hImc);
|
|
if (!pInputContext) {
|
|
RIPMSG1(RIP_WARNING, "ImmGenerateMessage: Lock hImc %lx failed.", hImc);
|
|
return FALSE;
|
|
}
|
|
|
|
iNum = (int)pInputContext->dwNumMsgBuf;
|
|
|
|
if (iNum && (lpdw = (LPDWORD)ImmLockIMCC(pInputContext->hMsgBuf))) {
|
|
LPDWORD lpdwTransKey, lpdwTransKeyT;
|
|
|
|
lpdwTransKey = ImmLocalAlloc(0, (iNum*3+1)*sizeof(DWORD));
|
|
if (lpdwTransKey != NULL) {
|
|
|
|
lpdwTransKeyT = lpdwTransKey;
|
|
*lpdwTransKeyT = iNum;
|
|
RtlCopyMemory(lpdwTransKeyT+1, lpdw, iNum*3*sizeof(DWORD));
|
|
|
|
#ifdef LATER
|
|
// Do WINNLSTranslateMessage() for old app. compatibility later.
|
|
#endif
|
|
|
|
lpdwTransKeyT++;
|
|
for (i = 0; i < iNum; i++) {
|
|
if (fUnicodeImc) {
|
|
SendMessageW((HWND)pInputContext->hWnd, (UINT)*lpdwTransKeyT,
|
|
(WPARAM)*(lpdwTransKeyT+1), (LPARAM)*(lpdwTransKeyT+2));
|
|
}
|
|
else {
|
|
SendMessageA((HWND)pInputContext->hWnd, (UINT)*lpdwTransKeyT,
|
|
(WPARAM)*(lpdwTransKeyT+1), (LPARAM)*(lpdwTransKeyT+2));
|
|
}
|
|
lpdwTransKeyT += 3;
|
|
}
|
|
|
|
ImmLocalFree(lpdwTransKey);
|
|
}
|
|
ImmUnlockIMCC(pInputContext->hMsgBuf);
|
|
}
|
|
|
|
/*
|
|
* We should not reallocate the message buffer
|
|
*/
|
|
pInputContext->dwNumMsgBuf = 0L;
|
|
|
|
ImmUnlockIMC(hImc);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmGetVirtualKey
|
|
*
|
|
* Gets the actual virtual key which is preprocessed by an IME.
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
UINT WINAPI ImmGetVirtualKey(
|
|
HWND hWnd)
|
|
{
|
|
HIMC hImc;
|
|
PINPUTCONTEXT pInputContext;
|
|
UINT uVirtKey;
|
|
|
|
hImc = ImmGetContext(hWnd);
|
|
|
|
pInputContext = ImmLockIMC(hImc);
|
|
if (!pInputContext) {
|
|
RIPMSG1(RIP_WARNING, "ImmGetVirtualKey: lock IMC %x failure", hImc);
|
|
return (VK_PROCESSKEY);
|
|
}
|
|
|
|
if (pInputContext->fChgMsg) {
|
|
uVirtKey = pInputContext->uSavedVKey;
|
|
} else {
|
|
uVirtKey = VK_PROCESSKEY;
|
|
}
|
|
|
|
ImmUnlockIMC(hImc);
|
|
return (uVirtKey);
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmLockIMC
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
PINPUTCONTEXT WINAPI ImmLockIMC(
|
|
HIMC hImc)
|
|
{
|
|
PCLIENTIMC pClientImc;
|
|
PINPUTCONTEXT pInputContext;
|
|
DWORD dwImcThreadId;
|
|
|
|
if ((pClientImc = ImmLockClientImc(hImc)) == NULL)
|
|
return NULL;
|
|
|
|
EnterImcCrit(pClientImc);
|
|
|
|
if (pClientImc->hInputContext == NULL) {
|
|
/*
|
|
* This is a delay creation of INPUTCONTEXT structure. Create
|
|
* it now for this hImc.
|
|
*/
|
|
pClientImc->hInputContext = LocalAlloc(LHND, sizeof(INPUTCONTEXT));
|
|
|
|
if (pClientImc->hInputContext == NULL) {
|
|
LeaveImcCrit(pClientImc);
|
|
ImmUnlockClientImc(pClientImc);
|
|
return NULL;
|
|
}
|
|
|
|
dwImcThreadId = NtUserQueryInputContext(hImc, InputContextThread);
|
|
|
|
if (!CreateInputContext(hImc, GetKeyboardLayout(dwImcThreadId))) {
|
|
RIPMSG0(RIP_WARNING, "ImmLockIMC: CreateInputContext failed");
|
|
LocalFree(pClientImc->hInputContext);
|
|
pClientImc->hInputContext = NULL;
|
|
LeaveImcCrit(pClientImc);
|
|
ImmUnlockClientImc(pClientImc);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
LeaveImcCrit(pClientImc);
|
|
|
|
pInputContext = (PINPUTCONTEXT)LocalLock(pClientImc->hInputContext);
|
|
|
|
/*
|
|
* Increment lock count so that the ImmUnlockClientImc() won't
|
|
* free up the pClientImc->hInputContext.
|
|
*/
|
|
InterlockedIncrement(&pClientImc->cLockObj);
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return pInputContext;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmUnlockIMC
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
BOOL WINAPI ImmUnlockIMC(
|
|
HIMC hImc)
|
|
{
|
|
PCLIENTIMC pClientImc;
|
|
|
|
if ((pClientImc = ImmLockClientImc(hImc)) == NULL)
|
|
return FALSE;
|
|
|
|
if (pClientImc->hInputContext != NULL)
|
|
LocalUnlock(pClientImc->hInputContext);
|
|
|
|
/*
|
|
* Decrement lock count so that the ImmUnlockClientImc() can
|
|
* free up the pClientImc->hInputContext if required.
|
|
*/
|
|
InterlockedDecrement(&pClientImc->cLockObj);
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmGetIMCLockCount
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
DWORD WINAPI ImmGetIMCLockCount(
|
|
HIMC hImc)
|
|
{
|
|
PCLIENTIMC pClientImc;
|
|
DWORD dwRet = 0;
|
|
|
|
if ((pClientImc = ImmLockClientImc(hImc)) == NULL)
|
|
return dwRet;
|
|
|
|
if (pClientImc->hInputContext != NULL)
|
|
dwRet = (DWORD)(LocalFlags(pClientImc->hInputContext) & LMEM_LOCKCOUNT);
|
|
|
|
ImmUnlockClientImc(pClientImc);
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmCreateIMCC
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
HIMCC WINAPI ImmCreateIMCC(
|
|
DWORD dwSize)
|
|
{
|
|
// At least size should be DWORD.
|
|
if (dwSize < sizeof(DWORD)) {
|
|
dwSize = sizeof(DWORD);
|
|
}
|
|
|
|
return (HIMCC)LocalAlloc(LHND, dwSize);
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmDestroyIMCC
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
HIMCC WINAPI ImmDestroyIMCC(
|
|
HIMCC hIMCC)
|
|
{
|
|
return (HIMCC)LocalFree((HLOCAL)hIMCC);
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmLockIMCC
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
LPVOID WINAPI ImmLockIMCC(
|
|
HIMCC hIMCC)
|
|
{
|
|
return LocalLock((HLOCAL)hIMCC);
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmUnlockIMCC
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
BOOL WINAPI ImmUnlockIMCC(
|
|
HIMCC hIMCC)
|
|
{
|
|
return LocalUnlock((HLOCAL)hIMCC);
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmGetIMCCLockCount
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
DWORD WINAPI ImmGetIMCCLockCount(
|
|
HIMCC hIMCC)
|
|
{
|
|
return (DWORD)(LocalFlags((HLOCAL)hIMCC) & LMEM_LOCKCOUNT);
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmReSizeIMCC
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
HIMCC WINAPI ImmReSizeIMCC(
|
|
HIMCC hIMCC,
|
|
DWORD dwSize)
|
|
{
|
|
return (HIMCC)LocalReAlloc((HLOCAL)hIMCC, dwSize, LHND);
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmGetIMCCSize
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
DWORD WINAPI ImmGetIMCCSize(
|
|
HIMCC hIMCC)
|
|
{
|
|
return (DWORD)LocalSize((HLOCAL)hIMCC);
|
|
}
|
|
|
|
|
|
/***************************************************************************\
|
|
* PtiCurrent
|
|
*
|
|
* Returns the THREADINFO structure for the current thread.
|
|
* LATER: Get DLL_THREAD_ATTACH initialization working right and we won't
|
|
* need this connect code.
|
|
*
|
|
* History:
|
|
* 10-28-90 DavidPe Created.
|
|
* 02-21-96 wkwok Copied from USER32.DLL
|
|
\***************************************************************************/
|
|
|
|
PTHREADINFO PtiCurrent(VOID)
|
|
{
|
|
PTHREADINFO pti;
|
|
|
|
pti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
|
|
if (pti == NULL) {
|
|
if (NtUserGetThreadState(-1) != (DWORD)STATUS_SUCCESS)
|
|
return NULL;
|
|
pti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
|
|
}
|
|
|
|
return pti;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* TestInputContextProcess
|
|
*
|
|
* 02-21-96 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
BOOL TestInputContextProcess(
|
|
PIMC pImc)
|
|
{
|
|
/*
|
|
* If the threads are the same, don't bother going to the kernel
|
|
* to get the input context's process id.
|
|
*/
|
|
if (GETPTI(pImc) == PtiCurrent()) {
|
|
return TRUE;
|
|
}
|
|
|
|
return (GetInputContextProcess((HIMC)PtoH(pImc)) == GETPROCESSID());
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* TestWindowProcess
|
|
*
|
|
* 11-14-94 JimA Created.
|
|
* 02-29-96 wkwok Copied from USER32.DLL
|
|
\**************************************************************************/
|
|
|
|
BOOL TestWindowProcess(
|
|
PWND pwnd)
|
|
{
|
|
/*
|
|
* If the threads are the same, don't bother going to the kernel
|
|
* to get the window's process id.
|
|
*/
|
|
if (GETPTI(pwnd) == PtiCurrent()) {
|
|
return TRUE;
|
|
}
|
|
|
|
return (GetWindowProcess(HW(pwnd)) == GETPROCESSID());
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* GetKeyboardLayoutCP
|
|
*
|
|
* 12-Mar-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
static LCID CachedLCID = 0;
|
|
static UINT CachedCP = CP_ACP;
|
|
|
|
UINT GetKeyboardLayoutCP(
|
|
HKL hKL)
|
|
{
|
|
#define LOCALE_CPDATA 7
|
|
WCHAR wszCodePage[LOCALE_CPDATA];
|
|
LCID lcid;
|
|
|
|
lcid = MAKELCID(LOWORD(hKL), SORT_DEFAULT);
|
|
|
|
if (lcid == CachedLCID)
|
|
return CachedCP;
|
|
|
|
if (!GetLocaleInfoW(lcid, LOCALE_IDEFAULTANSICODEPAGE,
|
|
wszCodePage, LOCALE_CPDATA))
|
|
return CP_ACP;
|
|
|
|
CachedLCID = lcid;
|
|
CachedCP = (UINT)wcstol(wszCodePage, NULL, 10);
|
|
|
|
return CachedCP;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* GetKeyboardLayoutCP
|
|
*
|
|
* 12-Mar-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
UINT GetThreadKeyboardLayoutCP(
|
|
DWORD dwThreadId)
|
|
{
|
|
HKL hKL;
|
|
|
|
hKL = GetKeyboardLayout(dwThreadId);
|
|
|
|
return GetKeyboardLayoutCP(hKL);
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmLockClientImc
|
|
*
|
|
* 13-Mar-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
PCLIENTIMC WINAPI ImmLockClientImc(
|
|
HIMC hImc)
|
|
{
|
|
PIMC pImc;
|
|
PCLIENTIMC pClientImc;
|
|
|
|
if (hImc == NULL_HIMC)
|
|
return NULL;
|
|
|
|
pImc = HMValidateHandle((HANDLE)hImc, TYPE_INPUTCONTEXT);
|
|
|
|
/*
|
|
* Cannot access input context from other process.
|
|
*/
|
|
if (pImc == NULL || !TestInputContextProcess(pImc))
|
|
return NULL;
|
|
|
|
pClientImc = (PCLIENTIMC)pImc->dwClientImcData;
|
|
|
|
if (pClientImc == NULL) {
|
|
/*
|
|
* We delay the creation of client side Imc. Now, this is
|
|
* the time to create it.
|
|
*/
|
|
pClientImc = ImmLocalAlloc(HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
|
|
if (pClientImc == NULL)
|
|
return NULL;
|
|
|
|
InitImcCrit(pClientImc);
|
|
pClientImc->hImc = hImc;
|
|
|
|
/*
|
|
* Update the kernel side input context.
|
|
*/
|
|
if (!NtUserUpdateInputContext(hImc,
|
|
UpdateClientInputContext, (DWORD)pClientImc)) {
|
|
ImmLocalFree(pClientImc);
|
|
return NULL;
|
|
}
|
|
}
|
|
else if (TestICF(pClientImc, IMCF_INDESTROY)) {
|
|
/*
|
|
* Cannot access destroyed input context.
|
|
*/
|
|
return NULL;
|
|
}
|
|
|
|
InterlockedIncrement(&pClientImc->cLockObj);
|
|
|
|
return pClientImc;
|
|
}
|
|
|
|
|
|
VOID WINAPI ImmUnlockClientImc(
|
|
PCLIENTIMC pClientImc)
|
|
{
|
|
if (InterlockedDecrement(&pClientImc->cLockObj) == 0) {
|
|
if (TestICF(pClientImc, IMCF_INDESTROY)) {
|
|
#ifdef DEBUG
|
|
PIMC pImc = HMValidateHandle((HANDLE)pClientImc->hImc, TYPE_INPUTCONTEXT);
|
|
ImmAssert(pImc == NULL || pImc->dwClientImcData == 0);
|
|
#endif
|
|
if (pClientImc->hInputContext != NULL)
|
|
LocalFree(pClientImc->hInputContext);
|
|
|
|
DeleteImcCrit(pClientImc);
|
|
ImmLocalFree(pClientImc);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**************************************************************************\
|
|
* ImmLockImeDpi
|
|
*
|
|
* 08-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
PIMEDPI WINAPI ImmLockImeDpi(
|
|
HKL hKL)
|
|
{
|
|
PIMEDPI pImeDpi;
|
|
|
|
RtlEnterCriticalSection(&gcsImeDpi);
|
|
|
|
pImeDpi = gpImeDpi;
|
|
|
|
while (pImeDpi != NULL) {
|
|
if (pImeDpi->hKL == hKL) {
|
|
pImeDpi->cLock++;
|
|
break;
|
|
}
|
|
pImeDpi = pImeDpi->pNext;
|
|
}
|
|
|
|
RtlLeaveCriticalSection(&gcsImeDpi);
|
|
|
|
return (PIMEDPI)pImeDpi;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmUnlockImeDpi
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
VOID WINAPI ImmUnlockImeDpi(
|
|
PIMEDPI pImeDpi)
|
|
{
|
|
#ifdef LATER
|
|
// Will implement free-on-unlock later.
|
|
#endif
|
|
if (pImeDpi != NULL)
|
|
pImeDpi->cLock--;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/**************************************************************************\
|
|
* ImmGetImeInfoEx
|
|
*
|
|
* 03-Jan-1996 wkwok Created
|
|
\**************************************************************************/
|
|
|
|
BOOL WINAPI ImmGetImeInfoEx(
|
|
PIMEINFOEX piiex,
|
|
IMEINFOEXCLASS SearchType,
|
|
PVOID pvSearchKey)
|
|
{
|
|
ImmAssert(piiex != NULL && pvSearchKey != NULL);
|
|
|
|
switch (SearchType) {
|
|
case ImeInfoExKeyboardLayout:
|
|
piiex->hkl = *((HKL *)pvSearchKey);
|
|
/*
|
|
* Quick return for non-IME based keyboard layout
|
|
*/
|
|
if (!IS_IME_KBDLAYOUT(piiex->hkl))
|
|
return FALSE;
|
|
break;
|
|
|
|
case ImeInfoExImeFileName:
|
|
wcscpy(piiex->wszImeFile, (PWSTR)pvSearchKey);
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return NtUserGetImeInfoEx(piiex, SearchType);
|
|
}
|