mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 20:36:26 +00:00
[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:
parent
2ab858c125
commit
a8d2cd4b9d
2 changed files with 78 additions and 34 deletions
|
@ -61,6 +61,32 @@ SHAREDINFO g_SharedInfo = { NULL };
|
|||
BYTE g_bClientRegd = FALSE;
|
||||
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)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
@ -120,6 +146,12 @@ static inline BOOL Imm32IsCrossThreadAccess(HIMC hIMC)
|
|||
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)
|
||||
{
|
||||
if (pImeDpi->hInst == NULL)
|
||||
|
@ -1862,6 +1894,40 @@ VOID WINAPI ImmUnlockClientImc(PCLIENTIMC 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
|
||||
CandidateListWideToAnsi(const CANDIDATELIST *pWideCL, LPCANDIDATELIST pAnsiCL, DWORD dwBufLen,
|
||||
UINT uCodePage)
|
||||
|
@ -2647,31 +2713,10 @@ BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, LPCOMPOSITIONFORM lpCompForm)
|
|||
*/
|
||||
HIMC WINAPI ImmGetContext(HWND hWnd)
|
||||
{
|
||||
HIMC rc;
|
||||
|
||||
TRACE("%p\n", hWnd);
|
||||
|
||||
if (!IsWindow(hWnd))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
|
||||
TRACE("(%p)\n", hWnd);
|
||||
if (hWnd == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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;
|
||||
return Imm32GetContextEx(hWnd, 2);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -2855,7 +2900,7 @@ UINT WINAPI ImmGetDescriptionA(
|
|||
lpszDescription, uBufLen, NULL, NULL);
|
||||
if (uBufLen)
|
||||
lpszDescription[cch] = 0;
|
||||
return cch;
|
||||
return (UINT)cch;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -3632,13 +3677,10 @@ Quit:
|
|||
*/
|
||||
BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
|
||||
{
|
||||
static BOOL shown = FALSE;
|
||||
|
||||
if (!shown) {
|
||||
FIXME("(%p, %p): stub\n", hWnd, hIMC);
|
||||
shown = TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
TRACE("(%p, %p)\n", hWnd, hIMC);
|
||||
UNREFERENCED_PARAMETER(hWnd);
|
||||
UNREFERENCED_PARAMETER(hIMC);
|
||||
return TRUE; // Do nothing. This is correct.
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -3698,7 +3740,7 @@ BOOL WINAPI ImmSetCandidateWindow(
|
|||
ImmUnlockIMC(hIMC);
|
||||
|
||||
Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS,
|
||||
IMN_SETCANDIDATEPOS, (1 << lpCandidate->dwIndex));
|
||||
IMN_SETCANDIDATEPOS, (1 << (BYTE)lpCandidate->dwIndex));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -3721,7 +3763,7 @@ static VOID APIENTRY AnsiToWideLogFont(const LOGFONTA *plfA, LPLOGFONTW plfW)
|
|||
RtlCopyMemory(plfW, plfA, offsetof(LOGFONTW, lfFaceName));
|
||||
StringCchLengthA(plfA->lfFaceName, _countof(plfA->lfFaceName), &cchA);
|
||||
cchW = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, plfA->lfFaceName, (INT)cchA,
|
||||
plfW->lfFaceName, cchW);
|
||||
plfW->lfFaceName, (INT)cchW);
|
||||
if (cchW > _countof(plfW->lfFaceName) - 1)
|
||||
cchW = _countof(plfW->lfFaceName) - 1;
|
||||
plfW->lfFaceName[cchW] = 0;
|
||||
|
@ -5106,6 +5148,7 @@ Quit:
|
|||
UINT WINAPI ImmWINNLSGetIMEHotkey(HWND hwndIme)
|
||||
{
|
||||
TRACE("(%p)\n", hwndIme);
|
||||
UNREFERENCED_PARAMETER(hwndIme);
|
||||
return 0; /* This is correct. This function of Windows just returns zero. */
|
||||
}
|
||||
|
||||
|
|
|
@ -1311,6 +1311,7 @@ C_ASSERT(sizeof(CLIENTIMC) == 0x34);
|
|||
/* flags for CLIENTIMC */
|
||||
#define CLIENTIMC_WIDE 0x1
|
||||
#define CLIENTIMC_UNKNOWN1 0x40
|
||||
#define CLIENTIMC_UNKNOWN3 0x80
|
||||
#define CLIENTIMC_UNKNOWN2 0x100
|
||||
|
||||
DWORD
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue