[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
This commit is contained in:
Katayama Hirofumi MZ 2022-02-13 15:51:53 +09:00 committed by GitHub
parent 78a7d7dc32
commit 45a4e53fa4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 64 additions and 65 deletions

View file

@ -638,50 +638,49 @@ BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
PIMC pIMC; PIMC pIMC;
if (!IS_IMM_MODE() || hIMC == NULL) if (!IS_IMM_MODE() || hIMC == NULL)
{
ERR("invalid HIMC\n");
return FALSE; return FALSE;
}
pIMC = ValidateHandleNoErr(hIMC, TYPE_INPUTCONTEXT); 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; return FALSE;
}
pClientImc = (PCLIENTIMC)pIMC->dwClientImcData; pClientImc = (PCLIENTIMC)pIMC->dwClientImcData;
if (!pClientImc) if (!pClientImc)
return FALSE; goto Finish;
if (pClientImc->hInputContext == NULL) if ((pClientImc->dwFlags & CLIENTIMC_UNKNOWN2) && !bKeep)
{ {
pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1; ERR("CLIENTIMC_UNKNOWN2\n");
ImmUnlockClientImc(pClientImc); return FALSE;
if (!bKeep)
return NtUserDestroyInputContext(hIMC);
return TRUE;
} }
if (pClientImc->dwFlags & CLIENTIMC_UNKNOWN1)
return TRUE;
InterlockedIncrement(&pClientImc->cLockObj);
if (!pClientImc->hInputContext)
goto Quit;
pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC); pIC = (LPINPUTCONTEXTDX)ImmLockIMC(hIMC);
if (pIC == NULL) if (!pIC)
{ {
ImmUnlockClientImc(pClientImc); ImmUnlockClientImc(pClientImc);
ERR("!pIC\n");
return FALSE; return FALSE;
} }
FIXME("We have do something to do here\n"); pImeDpi = ImmLockImeDpi(hKL);
if (pImeDpi)
if (pClientImc->hKL == hKL)
{ {
pImeDpi = ImmLockImeDpi(hKL); pImeDpi->ImeSelect(hIMC, FALSE);
if (pImeDpi != NULL) ImmUnlockImeDpi(pImeDpi);
{
if (IS_IME_HKL(hKL))
{
pImeDpi->ImeSelect(hIMC, FALSE);
}
else if (Imm32IsCiceroMode() && pImeDpi->CtfImeSelectEx)
{
pImeDpi->CtfImeSelectEx(hIMC, FALSE, hKL);
}
ImmUnlockImeDpi(pImeDpi);
}
pClientImc->hKL = NULL;
} }
pIC->hPrivate = ImmDestroyIMCC(pIC->hPrivate); pIC->hPrivate = ImmDestroyIMCC(pIC->hPrivate);
@ -689,18 +688,17 @@ BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine); pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo); pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr); pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
Imm32FreeImeStates(pIC); Imm32FreeImeStates(pIC);
ImmUnlockIMC(hIMC); ImmUnlockIMC(hIMC);
Quit:
pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1; pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1;
ImmUnlockClientImc(pClientImc); ImmUnlockClientImc(pClientImc);
if (!bKeep) Finish:
return NtUserDestroyInputContext(hIMC); if (bKeep)
return TRUE;
return TRUE; return NtUserDestroyInputContext(hIMC);
} }
BOOL APIENTRY BOOL APIENTRY
@ -1256,7 +1254,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{ {
HKL hKL; HKL hKL;
HIMC hIMC; HIMC hIMC;
PTEB pTeb;
TRACE("(%p, 0x%X, %p)\n", hinstDLL, fdwReason, lpReserved); TRACE("(%p, 0x%X, %p)\n", hinstDLL, fdwReason, lpReserved);
@ -1279,11 +1276,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
break; break;
case DLL_THREAD_DETACH: case DLL_THREAD_DETACH:
if (!IS_IMM_MODE()) if (!IS_IMM_MODE() || NtCurrentTeb()->Win32ThreadInfo == NULL)
return TRUE;
pTeb = NtCurrentTeb();
if (pTeb->Win32ThreadInfo == NULL)
return TRUE; return TRUE;
hKL = GetKeyboardLayout(0); hKL = GetKeyboardLayout(0);

View file

@ -574,7 +574,7 @@ LRESULT APIENTRY Imm32RequestMessageAW(HIMC hIMC, WPARAM wParam, LPARAM lParam,
if (hWnd) if (hWnd)
pWnd = ValidateHwndNoErr(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); ret = Imm32ProcessRequest(hIMC, pWnd, (DWORD)wParam, (LPVOID)lParam, bAnsi);
ImmUnlockIMC(hIMC); ImmUnlockIMC(hIMC);

View file

@ -156,3 +156,10 @@ UINT APIENTRY Imm32GetRegImes(PREG_IME pLayouts, UINT cLayouts);
BOOL APIENTRY Imm32WriteRegIme(HKL hKL, LPCWSTR pchFilePart, LPCWSTR pszLayout); BOOL APIENTRY Imm32WriteRegIme(HKL hKL, LPCWSTR pchFilePart, LPCWSTR pszLayout);
HKL APIENTRY Imm32GetNextHKL(UINT cKLs, const REG_IME *pLayouts, WORD wLangID); HKL APIENTRY Imm32GetNextHKL(UINT cKLs, const REG_IME *pLayouts, WORD wLangID);
BOOL APIENTRY Imm32CopyFile(LPWSTR pszOldFile, LPCWSTR pszNewFile); BOOL APIENTRY Imm32CopyFile(LPWSTR pszOldFile, LPCWSTR pszNewFile);
static inline PTHREADINFO FASTCALL Imm32CurrentPti(VOID)
{
if (NtCurrentTeb()->Win32ThreadInfo == NULL)
NtUserGetThreadState(THREADSTATE_GETTHREADINFO);
return NtCurrentTeb()->Win32ThreadInfo;
}

View file

@ -190,7 +190,7 @@ BOOL APIENTRY Imm32CheckImcProcess(PIMC pIMC)
{ {
HIMC hIMC; HIMC hIMC;
DWORD dwProcessID; DWORD dwProcessID;
if (pIMC->head.pti == NtCurrentTeb()->Win32ThreadInfo) if (pIMC->head.pti == Imm32CurrentPti())
return TRUE; return TRUE;
hIMC = pIMC->head.h; hIMC = pIMC->head.h;

View file

@ -1215,7 +1215,7 @@ typedef struct tagIMEUI
/* Window Extra data container. */ /* Window Extra data container. */
typedef struct _IMEWND typedef struct _IMEWND
{ {
WND; WND wnd;
PIMEUI pimeui; PIMEUI pimeui;
} IMEWND, *PIMEWND; } IMEWND, *PIMEWND;
@ -2570,8 +2570,7 @@ enum ThreadStateRoutines
THREADSTATE_ISWINLOGON, THREADSTATE_ISWINLOGON,
THREADSTATE_ISWINLOGON2, THREADSTATE_ISWINLOGON2,
THREADSTATE_UNKNOWN17, THREADSTATE_UNKNOWN17,
THREADSTATE_UNKNOWN18, THREADSTATE_GETTHREADINFO,
THREADSTATE_GETTHREADINFO = 100, /* FIXME: Delete this HACK */
THREADSTATE_PROGMANWINDOW, /* FIXME: Delete this HACK */ THREADSTATE_PROGMANWINDOW, /* FIXME: Delete this HACK */
THREADSTATE_TASKMANWINDOW, /* FIXME: Delete this HACK */ THREADSTATE_TASKMANWINDOW, /* FIXME: Delete this HACK */
}; };

View file

@ -1200,7 +1200,7 @@ AllocInputContextObject(PDESKTOP pDesk,
ASSERT(Size > sizeof(*ObjHead)); ASSERT(Size > sizeof(*ObjHead));
ASSERT(pti != NULL); ASSERT(pti != NULL);
ObjHead = UserHeapAlloc(Size); ObjHead = ExAllocatePoolWithTag(PagedPool, Size, USERTAG_IME);
if (!ObjHead) if (!ObjHead)
return NULL; return NULL;
@ -1218,7 +1218,7 @@ AllocInputContextObject(PDESKTOP pDesk,
VOID UserFreeInputContext(PVOID Object) VOID UserFreeInputContext(PVOID Object)
{ {
PIMC pIMC = Object, pImc0; PIMC pIMC = Object;
PTHREADINFO pti; PTHREADINFO pti;
if (!pIMC) if (!pIMC)
@ -1226,7 +1226,24 @@ VOID UserFreeInputContext(PVOID Object)
pti = pIMC->head.pti; 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 */ /* Find the IMC in the list and remove it */
pti = pIMC->head.pti;
for (pImc0 = pti->spDefaultImc; pImc0; pImc0 = pImc0->pImcNext) for (pImc0 = pti->spDefaultImc; pImc0; pImc0 = pImc0->pImcNext)
{ {
if (pImc0->pImcNext == pIMC) if (pImc0->pImcNext == pIMC)
@ -1236,21 +1253,7 @@ VOID UserFreeInputContext(PVOID Object)
} }
} }
UserHeapFree(pIMC); return UserDeleteObject(pIMC->head.h, TYPE_INPUTCONTEXT);
pti->ppi->UserHandleCount--;
IntDereferenceThreadInfo(pti);
}
BOOLEAN UserDestroyInputContext(PVOID Object)
{
PIMC pIMC = Object;
if (pIMC)
{
UserMarkObjectDestroy(pIMC);
UserDeleteObject(pIMC->head.h, TYPE_INPUTCONTEXT);
}
return TRUE;
} }
BOOL NTAPI NtUserDestroyInputContext(HIMC hIMC) BOOL NTAPI NtUserDestroyInputContext(HIMC hIMC)

View file

@ -248,8 +248,8 @@ NtUserGetThreadState(
switch (Routine) switch (Routine)
{ {
case THREADSTATE_GETTHREADINFO: /* FIXME: Delete this HACK */ case THREADSTATE_GETTHREADINFO:
GetW32ThreadInfo(); ret = TRUE;
break; break;
case THREADSTATE_FOCUSWINDOW: case THREADSTATE_FOCUSWINDOW:
ret = (DWORD_PTR)IntGetThreadFocusWindow(); ret = (DWORD_PTR)IntGetThreadFocusWindow();
@ -337,9 +337,6 @@ NtUserGetThreadState(
case THREADSTATE_UNKNOWN17: case THREADSTATE_UNKNOWN17:
/* FIXME */ /* FIXME */
break; break;
case THREADSTATE_UNKNOWN18:
ret = TRUE;
break;
} }
TRACE("Leave NtUserGetThreadState, ret=%lu\n", ret); TRACE("Leave NtUserGetThreadState, ret=%lu\n", ret);