[IMM32] Rewrite ImmGetContext (#3923)

- Add ValidateHwndNoErr and Imm32GetContextEx helper functions.
- Rewrite ImmGetContext function by using the helper functions.
CORE-11700
This commit is contained in:
Katayama Hirofumi MZ 2021-08-24 06:50:39 +09:00 committed by GitHub
parent 2ab858c125
commit a8d2cd4b9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 34 deletions

View file

@ -61,6 +61,32 @@ SHAREDINFO g_SharedInfo = { NULL };
BYTE g_bClientRegd = FALSE; BYTE g_bClientRegd = FALSE;
HANDLE g_hImm32Heap = NULL; HANDLE g_hImm32Heap = NULL;
static PWND FASTCALL ValidateHwndNoErr(HWND hwnd)
{
PCLIENTINFO ClientInfo = GetWin32ClientInfo();
INT index;
PUSER_HANDLE_TABLE ht;
WORD generation;
/* See if the window is cached */
if (hwnd == ClientInfo->CallbackWnd.hWnd)
return ClientInfo->CallbackWnd.pWnd;
if (!NtUserValidateHandleSecure(hwnd))
return NULL;
ht = g_SharedInfo.aheList; /* handle table */
index = (LOWORD(hwnd) - FIRST_USER_HANDLE) >> 1;
if (index < 0 || index >= ht->nb_handles || ht->handles[index].type != TYPE_WINDOW)
return NULL;
generation = HIWORD(hwnd);
if (generation != ht->handles[index].generation && generation && generation != 0xFFFF)
return NULL;
return (PWND)&ht->handles[index];
}
static BOOL APIENTRY Imm32InitInstance(HMODULE hMod) static BOOL APIENTRY Imm32InitInstance(HMODULE hMod)
{ {
NTSTATUS status; NTSTATUS status;
@ -120,6 +146,12 @@ static inline BOOL Imm32IsCrossThreadAccess(HIMC hIMC)
return (dwImeThreadId != dwThreadId); return (dwImeThreadId != dwThreadId);
} }
static BOOL Imm32IsCrossProcessAccess(HWND hWnd)
{
return (NtUserQueryWindow(hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID) !=
(DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess);
}
static VOID APIENTRY Imm32FreeImeDpi(PIMEDPI pImeDpi, BOOL bDestroy) static VOID APIENTRY Imm32FreeImeDpi(PIMEDPI pImeDpi, BOOL bDestroy)
{ {
if (pImeDpi->hInst == NULL) if (pImeDpi->hInst == NULL)
@ -1862,6 +1894,40 @@ VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
HeapFree(g_hImm32Heap, 0, pClientImc); HeapFree(g_hImm32Heap, 0, pClientImc);
} }
static HIMC APIENTRY Imm32GetContextEx(HWND hWnd, DWORD dwContextFlags)
{
HIMC hIMC;
PCLIENTIMC pClientImc;
PWND pWnd;
if (!g_psi || !(g_psi->dwSRVIFlags & SRVINFO_IMM32))
return NULL;
if (!hWnd)
{
// FIXME: NtUserGetThreadState and enum ThreadStateRoutines are broken.
hIMC = (HIMC)NtUserGetThreadState(4);
goto Quit;
}
pWnd = ValidateHwndNoErr(hWnd);
if (!pWnd || Imm32IsCrossProcessAccess(hWnd))
return NULL;
hIMC = pWnd->hImc;
if (!hIMC && (dwContextFlags & 1))
hIMC = (HIMC)NtUserQueryWindow(hWnd, QUERY_WINDOW_DEFAULT_ICONTEXT);
Quit:
pClientImc = ImmLockClientImc(hIMC);
if (pClientImc == NULL)
return NULL;
if ((dwContextFlags & 2) && (pClientImc->dwFlags & CLIENTIMC_UNKNOWN3))
hIMC = NULL;
ImmUnlockClientImc(pClientImc);
return hIMC;
}
static DWORD APIENTRY static DWORD APIENTRY
CandidateListWideToAnsi(const CANDIDATELIST *pWideCL, LPCANDIDATELIST pAnsiCL, DWORD dwBufLen, CandidateListWideToAnsi(const CANDIDATELIST *pWideCL, LPCANDIDATELIST pAnsiCL, DWORD dwBufLen,
UINT uCodePage) UINT uCodePage)
@ -2647,31 +2713,10 @@ BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
*/ */
HIMC WINAPI ImmGetContext(HWND hWnd) HIMC WINAPI ImmGetContext(HWND hWnd)
{ {
HIMC rc; TRACE("(%p)\n", hWnd);
if (hWnd == NULL)
TRACE("%p\n", hWnd);
if (!IsWindow(hWnd))
{
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
return NULL; return NULL;
} return Imm32GetContextEx(hWnd, 2);
rc = GetPropW(hWnd,szwWineIMCProperty);
if (rc == (HIMC)-1)
rc = NULL;
else if (rc == NULL)
rc = get_default_context( hWnd );
if (rc)
{
InputContextData *data = (InputContextData *)rc;
data->IMC.hWnd = hWnd;
}
TRACE("returning %p\n", rc);
return rc;
} }
/*********************************************************************** /***********************************************************************
@ -2855,7 +2900,7 @@ UINT WINAPI ImmGetDescriptionA(
lpszDescription, uBufLen, NULL, NULL); lpszDescription, uBufLen, NULL, NULL);
if (uBufLen) if (uBufLen)
lpszDescription[cch] = 0; lpszDescription[cch] = 0;
return cch; return (UINT)cch;
} }
/*********************************************************************** /***********************************************************************
@ -3632,13 +3677,10 @@ Quit:
*/ */
BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC) BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
{ {
static BOOL shown = FALSE; TRACE("(%p, %p)\n", hWnd, hIMC);
UNREFERENCED_PARAMETER(hWnd);
if (!shown) { UNREFERENCED_PARAMETER(hIMC);
FIXME("(%p, %p): stub\n", hWnd, hIMC); return TRUE; // Do nothing. This is correct.
shown = TRUE;
}
return TRUE;
} }
/*********************************************************************** /***********************************************************************
@ -3698,7 +3740,7 @@ BOOL WINAPI ImmSetCandidateWindow(
ImmUnlockIMC(hIMC); ImmUnlockIMC(hIMC);
Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS, Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS,
IMN_SETCANDIDATEPOS, (1 << lpCandidate->dwIndex)); IMN_SETCANDIDATEPOS, (1 << (BYTE)lpCandidate->dwIndex));
return TRUE; return TRUE;
} }
@ -3721,7 +3763,7 @@ static VOID APIENTRY AnsiToWideLogFont(const LOGFONTA *plfA, LPLOGFONTW plfW)
RtlCopyMemory(plfW, plfA, offsetof(LOGFONTW, lfFaceName)); RtlCopyMemory(plfW, plfA, offsetof(LOGFONTW, lfFaceName));
StringCchLengthA(plfA->lfFaceName, _countof(plfA->lfFaceName), &cchA); StringCchLengthA(plfA->lfFaceName, _countof(plfA->lfFaceName), &cchA);
cchW = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, plfA->lfFaceName, (INT)cchA, cchW = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, plfA->lfFaceName, (INT)cchA,
plfW->lfFaceName, cchW); plfW->lfFaceName, (INT)cchW);
if (cchW > _countof(plfW->lfFaceName) - 1) if (cchW > _countof(plfW->lfFaceName) - 1)
cchW = _countof(plfW->lfFaceName) - 1; cchW = _countof(plfW->lfFaceName) - 1;
plfW->lfFaceName[cchW] = 0; plfW->lfFaceName[cchW] = 0;
@ -5106,6 +5148,7 @@ Quit:
UINT WINAPI ImmWINNLSGetIMEHotkey(HWND hwndIme) UINT WINAPI ImmWINNLSGetIMEHotkey(HWND hwndIme)
{ {
TRACE("(%p)\n", hwndIme); TRACE("(%p)\n", hwndIme);
UNREFERENCED_PARAMETER(hwndIme);
return 0; /* This is correct. This function of Windows just returns zero. */ return 0; /* This is correct. This function of Windows just returns zero. */
} }

View file

@ -1311,6 +1311,7 @@ C_ASSERT(sizeof(CLIENTIMC) == 0x34);
/* flags for CLIENTIMC */ /* flags for CLIENTIMC */
#define CLIENTIMC_WIDE 0x1 #define CLIENTIMC_WIDE 0x1
#define CLIENTIMC_UNKNOWN1 0x40 #define CLIENTIMC_UNKNOWN1 0x40
#define CLIENTIMC_UNKNOWN3 0x80
#define CLIENTIMC_UNKNOWN2 0x100 #define CLIENTIMC_UNKNOWN2 0x100
DWORD DWORD