[NTUSER] Use assignment-lock against THREADINFO.KeyboardLayout (#4620)

- Assignment and locking are managed by UserAssignmentLock/UserAssignmentUnlock.
- Synchronize ClientInfo->hKL to pti->KeyboardLayout->hkl.
CORE-11700, CORE-18317
This commit is contained in:
Katayama Hirofumi MZ 2022-08-23 19:32:23 +09:00 committed by GitHub
parent 5cadc268ef
commit f34b8460e3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 24 deletions

View file

@ -533,6 +533,7 @@ NtUserSetThreadLayoutHandles(HKL hNewKL, HKL hOldKL)
pti->hklPrev = hOldKL; pti->hklPrev = hOldKL;
UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pNewKL); UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pNewKL);
pti->pClientInfo->hKL = pNewKL->hkl;
Quit: Quit:
UserLeave(); UserLeave();

View file

@ -583,16 +583,13 @@ co_UserActivateKbl(PTHREADINFO pti, PKL pKl, UINT Flags)
PWND pWnd; PWND pWnd;
pklPrev = pti->KeyboardLayout; pklPrev = pti->KeyboardLayout;
if (pklPrev)
UserDereferenceObject(pklPrev);
pti->KeyboardLayout = pKl; UserAssignmentLock((PVOID*)&(pti->KeyboardLayout), pKl);
pti->pClientInfo->hKL = pKl->hkl; pti->pClientInfo->hKL = pKl->hkl;
UserReferenceObject(pKl);
if (Flags & KLF_SETFORPROCESS) if (Flags & KLF_SETFORPROCESS)
{ {
// FIXME FIXME("KLF_SETFORPROCESS\n");
} }
if (!(pWnd = pti->MessageQueue->spwndFocus)) if (!(pWnd = pti->MessageQueue->spwndFocus))
@ -631,7 +628,8 @@ IntImmActivateLayout(
UserDerefObjectCo(pImeWnd); UserDerefObjectCo(pImeWnd);
} }
UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pKL); UserAssignmentLock((PVOID*)&(pti->KeyboardLayout), pKL);
pti->pClientInfo->hKL = pKL->hkl;
} }
/* Win: xxxInternalActivateKeyboardLayout */ /* Win: xxxInternalActivateKeyboardLayout */
@ -658,7 +656,7 @@ co_UserActivateKeyboardLayout(
if (uFlags & KLF_RESET) if (uFlags & KLF_RESET)
{ {
/* FIXME */ FIXME("KLF_RESET\n");
} }
if (!(uFlags & KLF_SETFORPROCESS) && pKL == pti->KeyboardLayout) if (!(uFlags & KLF_SETFORPROCESS) && pKL == pti->KeyboardLayout)
@ -673,10 +671,11 @@ co_UserActivateKeyboardLayout(
{ {
UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pKL); UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pKL);
ClientInfo->CodePage = pKL->CodePage; ClientInfo->CodePage = pKL->CodePage;
ClientInfo->hKL = pKL->hkl;
} }
else if (uFlags & KLF_SETFORPROCESS) else if (uFlags & KLF_SETFORPROCESS)
{ {
/* FIXME */ FIXME("KLF_SETFORPROCESS\n");
} }
else else
{ {
@ -685,11 +684,8 @@ co_UserActivateKeyboardLayout(
else else
UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pKL); UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pKL);
if (!(pti->TIF_flags & TIF_INCLEANUP)) ClientInfo->CodePage = pKL->CodePage;
{ ClientInfo->hKL = pKL->hkl;
ClientInfo->CodePage = pKL->CodePage;
ClientInfo->hKL = pKL->hkl;
}
} }
if (gptiForeground && (gptiForeground->ppi == pti->ppi)) if (gptiForeground && (gptiForeground->ppi == pti->ppi))

View file

@ -1174,9 +1174,18 @@ IntTranslateKbdMessage(LPMSG lpMsg,
if (!pti->KeyboardLayout) if (!pti->KeyboardLayout)
{ {
pti->KeyboardLayout = W32kGetDefaultKeyLayout(); PKL pDefKL = W32kGetDefaultKeyLayout();
pti->pClientInfo->hKL = pti->KeyboardLayout ? pti->KeyboardLayout->hkl : NULL; UserAssignmentLock((PVOID*)&(pti->KeyboardLayout), pDefKL);
pKbdTbl = pti->KeyboardLayout ? pti->KeyboardLayout->spkf->pKbdTbl : NULL; if (pDefKL)
{
pti->pClientInfo->hKL = pDefKL->hkl;
pKbdTbl = pDefKL->spkf->pKbdTbl;
}
else
{
pti->pClientInfo->hKL = NULL;
pKbdTbl = NULL;
}
} }
else else
pKbdTbl = pti->KeyboardLayout->spkf->pKbdTbl; pKbdTbl = pti->KeyboardLayout->spkf->pKbdTbl;

View file

@ -462,6 +462,7 @@ InitThreadCallback(PETHREAD Thread)
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PTEB pTeb; PTEB pTeb;
PRTL_USER_PROCESS_PARAMETERS ProcessParams; PRTL_USER_PROCESS_PARAMETERS ProcessParams;
PKL pDefKL;
Process = Thread->ThreadsProcess; Process = Thread->ThreadsProcess;
@ -532,9 +533,8 @@ InitThreadCallback(PETHREAD Thread)
goto error; goto error;
} }
ptiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout(); pDefKL = W32kGetDefaultKeyLayout();
if (ptiCurrent->KeyboardLayout) UserAssignmentLock((PVOID*)&(ptiCurrent->KeyboardLayout), pDefKL);
UserReferenceObject(ptiCurrent->KeyboardLayout);
ptiCurrent->TIF_flags &= ~TIF_INCLEANUP; ptiCurrent->TIF_flags &= ~TIF_INCLEANUP;
@ -550,10 +550,10 @@ InitThreadCallback(PETHREAD Thread)
pci->ppi = ptiCurrent->ppi; pci->ppi = ptiCurrent->ppi;
pci->fsHooks = ptiCurrent->fsHooks; pci->fsHooks = ptiCurrent->fsHooks;
pci->dwTIFlags = ptiCurrent->TIF_flags; pci->dwTIFlags = ptiCurrent->TIF_flags;
if (ptiCurrent->KeyboardLayout) if (pDefKL)
{ {
pci->hKL = ptiCurrent->KeyboardLayout->hkl; pci->hKL = pDefKL->hkl;
pci->CodePage = ptiCurrent->KeyboardLayout->CodePage; pci->CodePage = pDefKL->CodePage;
} }
/* Need to pass the user Startup Information to the current process. */ /* Need to pass the user Startup Information to the current process. */
@ -829,8 +829,8 @@ ExitThreadCallback(PETHREAD Thread)
/* Remove it from the list */ /* Remove it from the list */
*ppti = ptiCurrent->ptiSibling; *ppti = ptiCurrent->ptiSibling;
if (ptiCurrent->KeyboardLayout) if (!UserAssignmentUnlock((PVOID*)&(ptiCurrent->KeyboardLayout)))
UserDereferenceObject(ptiCurrent->KeyboardLayout); ptiCurrent->pClientInfo->hKL = NULL;
if (gptiForeground == ptiCurrent) if (gptiForeground == ptiCurrent)
{ {