mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 14:25:52 +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;
|
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. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue