From 45a4e53fa454f5ad4e8b96ddf04c30ad77b1af2a Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sun, 13 Feb 2022 15:51:53 +0900 Subject: [PATCH] [NTUSER][IMM32] Use Imm32CurrentPti and pool (#4356) - Use newly-defined Imm32CurrentPti() instead of NtCurrentTeb()->Win32ThreadInfo. - THREADSTATE_GETTHREADINFO is same as THREADSTATE_UNKNOWN18. - Use the paged pool to allocate HIMC rather than heap. - Fix and improve ImmDestroyContext function. CORE-11700 --- dll/win32/imm32/imm.c | 69 +++++++++++++++++--------------------- dll/win32/imm32/keymsg.c | 2 +- dll/win32/imm32/precomp.h | 7 ++++ dll/win32/imm32/utils.c | 2 +- win32ss/include/ntuser.h | 5 ++- win32ss/user/ntuser/ime.c | 37 ++++++++++---------- win32ss/user/ntuser/misc.c | 7 ++-- 7 files changed, 64 insertions(+), 65 deletions(-) diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c index d0ecbd2103c..1d80bf28232 100644 --- a/dll/win32/imm32/imm.c +++ b/dll/win32/imm32/imm.c @@ -638,50 +638,49 @@ BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep) PIMC pIMC; if (!IS_IMM_MODE() || hIMC == NULL) + { + ERR("invalid HIMC\n"); return FALSE; + } pIMC = ValidateHandleNoErr(hIMC, TYPE_INPUTCONTEXT); - if (!pIMC || pIMC->head.pti != NtCurrentTeb()->Win32ThreadInfo) + if (!pIMC || pIMC->head.pti != Imm32CurrentPti()) + { + ERR("invalid pIMC: %p\n", pIMC); return FALSE; + } pClientImc = (PCLIENTIMC)pIMC->dwClientImcData; if (!pClientImc) - return FALSE; + goto Finish; - if (pClientImc->hInputContext == NULL) + if ((pClientImc->dwFlags & CLIENTIMC_UNKNOWN2) && !bKeep) { - pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1; - ImmUnlockClientImc(pClientImc); - if (!bKeep) - return NtUserDestroyInputContext(hIMC); - return TRUE; + ERR("CLIENTIMC_UNKNOWN2\n"); + return FALSE; } + if (pClientImc->dwFlags & CLIENTIMC_UNKNOWN1) + return TRUE; + + InterlockedIncrement(&pClientImc->cLockObj); + + if (!pClientImc->hInputContext) + goto Quit; + pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC); - if (pIC == NULL) + if (!pIC) { ImmUnlockClientImc(pClientImc); + ERR("!pIC\n"); return FALSE; } - FIXME("We have do something to do here\n"); - - if (pClientImc->hKL == hKL) + pImeDpi = ImmLockImeDpi(hKL); + if (pImeDpi) { - pImeDpi = ImmLockImeDpi(hKL); - if (pImeDpi != NULL) - { - if (IS_IME_HKL(hKL)) - { - pImeDpi->ImeSelect(hIMC, FALSE); - } - else if (Imm32IsCiceroMode() && pImeDpi->CtfImeSelectEx) - { - pImeDpi->CtfImeSelectEx(hIMC, FALSE, hKL); - } - ImmUnlockImeDpi(pImeDpi); - } - pClientImc->hKL = NULL; + pImeDpi->ImeSelect(hIMC, FALSE); + ImmUnlockImeDpi(pImeDpi); } pIC->hPrivate = ImmDestroyIMCC(pIC->hPrivate); @@ -689,18 +688,17 @@ BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep) pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine); pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo); pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr); - Imm32FreeImeStates(pIC); - ImmUnlockIMC(hIMC); +Quit: pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1; ImmUnlockClientImc(pClientImc); - if (!bKeep) - return NtUserDestroyInputContext(hIMC); - - return TRUE; +Finish: + if (bKeep) + return TRUE; + return NtUserDestroyInputContext(hIMC); } BOOL APIENTRY @@ -1256,7 +1254,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { HKL hKL; HIMC hIMC; - PTEB pTeb; TRACE("(%p, 0x%X, %p)\n", hinstDLL, fdwReason, lpReserved); @@ -1279,11 +1276,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) break; case DLL_THREAD_DETACH: - if (!IS_IMM_MODE()) - return TRUE; - - pTeb = NtCurrentTeb(); - if (pTeb->Win32ThreadInfo == NULL) + if (!IS_IMM_MODE() || NtCurrentTeb()->Win32ThreadInfo == NULL) return TRUE; hKL = GetKeyboardLayout(0); diff --git a/dll/win32/imm32/keymsg.c b/dll/win32/imm32/keymsg.c index a8fa1d84b83..0b5baaf7e88 100644 --- a/dll/win32/imm32/keymsg.c +++ b/dll/win32/imm32/keymsg.c @@ -574,7 +574,7 @@ LRESULT APIENTRY Imm32RequestMessageAW(HIMC hIMC, WPARAM wParam, LPARAM lParam, if (hWnd) pWnd = ValidateHwndNoErr(hWnd); - if (pWnd && pWnd->head.pti == NtCurrentTeb()->Win32ThreadInfo) + if (pWnd && pWnd->head.pti == Imm32CurrentPti()) ret = Imm32ProcessRequest(hIMC, pWnd, (DWORD)wParam, (LPVOID)lParam, bAnsi); ImmUnlockIMC(hIMC); diff --git a/dll/win32/imm32/precomp.h b/dll/win32/imm32/precomp.h index 1d5319dc340..3de40f0cbc0 100644 --- a/dll/win32/imm32/precomp.h +++ b/dll/win32/imm32/precomp.h @@ -156,3 +156,10 @@ UINT APIENTRY Imm32GetRegImes(PREG_IME pLayouts, UINT cLayouts); BOOL APIENTRY Imm32WriteRegIme(HKL hKL, LPCWSTR pchFilePart, LPCWSTR pszLayout); HKL APIENTRY Imm32GetNextHKL(UINT cKLs, const REG_IME *pLayouts, WORD wLangID); BOOL APIENTRY Imm32CopyFile(LPWSTR pszOldFile, LPCWSTR pszNewFile); + +static inline PTHREADINFO FASTCALL Imm32CurrentPti(VOID) +{ + if (NtCurrentTeb()->Win32ThreadInfo == NULL) + NtUserGetThreadState(THREADSTATE_GETTHREADINFO); + return NtCurrentTeb()->Win32ThreadInfo; +} diff --git a/dll/win32/imm32/utils.c b/dll/win32/imm32/utils.c index 86be064c251..8c3d8ad3c11 100644 --- a/dll/win32/imm32/utils.c +++ b/dll/win32/imm32/utils.c @@ -190,7 +190,7 @@ BOOL APIENTRY Imm32CheckImcProcess(PIMC pIMC) { HIMC hIMC; DWORD dwProcessID; - if (pIMC->head.pti == NtCurrentTeb()->Win32ThreadInfo) + if (pIMC->head.pti == Imm32CurrentPti()) return TRUE; hIMC = pIMC->head.h; diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h index 95bd2db0a67..326bc9aefbe 100644 --- a/win32ss/include/ntuser.h +++ b/win32ss/include/ntuser.h @@ -1215,7 +1215,7 @@ typedef struct tagIMEUI /* Window Extra data container. */ typedef struct _IMEWND { - WND; + WND wnd; PIMEUI pimeui; } IMEWND, *PIMEWND; @@ -2570,8 +2570,7 @@ enum ThreadStateRoutines THREADSTATE_ISWINLOGON, THREADSTATE_ISWINLOGON2, THREADSTATE_UNKNOWN17, - THREADSTATE_UNKNOWN18, - THREADSTATE_GETTHREADINFO = 100, /* FIXME: Delete this HACK */ + THREADSTATE_GETTHREADINFO, THREADSTATE_PROGMANWINDOW, /* FIXME: Delete this HACK */ THREADSTATE_TASKMANWINDOW, /* FIXME: Delete this HACK */ }; diff --git a/win32ss/user/ntuser/ime.c b/win32ss/user/ntuser/ime.c index f7c67164c4e..14771e828ac 100644 --- a/win32ss/user/ntuser/ime.c +++ b/win32ss/user/ntuser/ime.c @@ -1200,7 +1200,7 @@ AllocInputContextObject(PDESKTOP pDesk, ASSERT(Size > sizeof(*ObjHead)); ASSERT(pti != NULL); - ObjHead = UserHeapAlloc(Size); + ObjHead = ExAllocatePoolWithTag(PagedPool, Size, USERTAG_IME); if (!ObjHead) return NULL; @@ -1218,7 +1218,7 @@ AllocInputContextObject(PDESKTOP pDesk, VOID UserFreeInputContext(PVOID Object) { - PIMC pIMC = Object, pImc0; + PIMC pIMC = Object; PTHREADINFO pti; if (!pIMC) @@ -1226,7 +1226,24 @@ VOID UserFreeInputContext(PVOID Object) pti = pIMC->head.pti; + ExFreePoolWithTag(pIMC, USERTAG_IME); + + pti->ppi->UserHandleCount--; + IntDereferenceThreadInfo(pti); +} + +BOOLEAN UserDestroyInputContext(PVOID Object) +{ + PIMC pIMC = Object, pImc0; + PTHREADINFO pti; + + if (!pIMC) + return TRUE; + + UserMarkObjectDestroy(pIMC); + /* Find the IMC in the list and remove it */ + pti = pIMC->head.pti; for (pImc0 = pti->spDefaultImc; pImc0; pImc0 = pImc0->pImcNext) { if (pImc0->pImcNext == pIMC) @@ -1236,21 +1253,7 @@ VOID UserFreeInputContext(PVOID Object) } } - UserHeapFree(pIMC); - - pti->ppi->UserHandleCount--; - IntDereferenceThreadInfo(pti); -} - -BOOLEAN UserDestroyInputContext(PVOID Object) -{ - PIMC pIMC = Object; - if (pIMC) - { - UserMarkObjectDestroy(pIMC); - UserDeleteObject(pIMC->head.h, TYPE_INPUTCONTEXT); - } - return TRUE; + return UserDeleteObject(pIMC->head.h, TYPE_INPUTCONTEXT); } BOOL NTAPI NtUserDestroyInputContext(HIMC hIMC) diff --git a/win32ss/user/ntuser/misc.c b/win32ss/user/ntuser/misc.c index 8fa8b0edb4d..970d1b6c46d 100644 --- a/win32ss/user/ntuser/misc.c +++ b/win32ss/user/ntuser/misc.c @@ -248,8 +248,8 @@ NtUserGetThreadState( switch (Routine) { - case THREADSTATE_GETTHREADINFO: /* FIXME: Delete this HACK */ - GetW32ThreadInfo(); + case THREADSTATE_GETTHREADINFO: + ret = TRUE; break; case THREADSTATE_FOCUSWINDOW: ret = (DWORD_PTR)IntGetThreadFocusWindow(); @@ -337,9 +337,6 @@ NtUserGetThreadState( case THREADSTATE_UNKNOWN17: /* FIXME */ break; - case THREADSTATE_UNKNOWN18: - ret = TRUE; - break; } TRACE("Leave NtUserGetThreadState, ret=%lu\n", ret);