https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f34b8460e33fd64afa9ac…
commit f34b8460e33fd64afa9acc1fe3827dfedf00f2d9
Author:     Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Tue Aug 23 19:32:23 2022 +0900
Commit:     GitHub <noreply(a)github.com>
CommitDate: Tue Aug 23 19:32:23 2022 +0900
    [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
---
 win32ss/user/ntuser/ime.c       |  1 +
 win32ss/user/ntuser/kbdlayout.c | 22 +++++++++-------------
 win32ss/user/ntuser/keyboard.c  | 15 ++++++++++++---
 win32ss/user/ntuser/main.c      | 16 ++++++++--------
 4 files changed, 30 insertions(+), 24 deletions(-)
diff --git a/win32ss/user/ntuser/ime.c b/win32ss/user/ntuser/ime.c
index 370854ad2e8..1cdabee6638 100644
--- a/win32ss/user/ntuser/ime.c
+++ b/win32ss/user/ntuser/ime.c
@@ -533,6 +533,7 @@ NtUserSetThreadLayoutHandles(HKL hNewKL, HKL hOldKL)
         pti->hklPrev = hOldKL;
     UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pNewKL);
+    pti->pClientInfo->hKL = pNewKL->hkl;
 Quit:
     UserLeave();
diff --git a/win32ss/user/ntuser/kbdlayout.c b/win32ss/user/ntuser/kbdlayout.c
index fde11969f9b..6a742b27377 100644
--- a/win32ss/user/ntuser/kbdlayout.c
+++ b/win32ss/user/ntuser/kbdlayout.c
@@ -583,16 +583,13 @@ co_UserActivateKbl(PTHREADINFO pti, PKL pKl, UINT Flags)
     PWND pWnd;
     pklPrev = pti->KeyboardLayout;
-    if (pklPrev)
-        UserDereferenceObject(pklPrev);
-    pti->KeyboardLayout = pKl;
+    UserAssignmentLock((PVOID*)&(pti->KeyboardLayout), pKl);
     pti->pClientInfo->hKL = pKl->hkl;
-    UserReferenceObject(pKl);
     if (Flags & KLF_SETFORPROCESS)
     {
-        // FIXME
+        FIXME("KLF_SETFORPROCESS\n");
     }
     if (!(pWnd = pti->MessageQueue->spwndFocus))
@@ -631,7 +628,8 @@ IntImmActivateLayout(
         UserDerefObjectCo(pImeWnd);
     }
-    UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pKL);
+    UserAssignmentLock((PVOID*)&(pti->KeyboardLayout), pKL);
+    pti->pClientInfo->hKL = pKL->hkl;
 }
 /* Win: xxxInternalActivateKeyboardLayout */
@@ -658,7 +656,7 @@ co_UserActivateKeyboardLayout(
     if (uFlags & KLF_RESET)
     {
-        /* FIXME */
+        FIXME("KLF_RESET\n");
     }
     if (!(uFlags & KLF_SETFORPROCESS) && pKL == pti->KeyboardLayout)
@@ -673,10 +671,11 @@ co_UserActivateKeyboardLayout(
     {
         UserAssignmentLock((PVOID*)&pti->KeyboardLayout, pKL);
         ClientInfo->CodePage = pKL->CodePage;
+        ClientInfo->hKL = pKL->hkl;
     }
     else if (uFlags & KLF_SETFORPROCESS)
     {
-        /* FIXME */
+        FIXME("KLF_SETFORPROCESS\n");
     }
     else
     {
@@ -685,11 +684,8 @@ co_UserActivateKeyboardLayout(
         else
             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))
diff --git a/win32ss/user/ntuser/keyboard.c b/win32ss/user/ntuser/keyboard.c
index 3ecc03ff433..3d427d1cb0b 100644
--- a/win32ss/user/ntuser/keyboard.c
+++ b/win32ss/user/ntuser/keyboard.c
@@ -1174,9 +1174,18 @@ IntTranslateKbdMessage(LPMSG lpMsg,
     if (!pti->KeyboardLayout)
     {
-       pti->KeyboardLayout = W32kGetDefaultKeyLayout();
-       pti->pClientInfo->hKL = pti->KeyboardLayout ?
pti->KeyboardLayout->hkl : NULL;
-       pKbdTbl = pti->KeyboardLayout ? pti->KeyboardLayout->spkf->pKbdTbl :
NULL;
+        PKL pDefKL = W32kGetDefaultKeyLayout();
+        UserAssignmentLock((PVOID*)&(pti->KeyboardLayout), pDefKL);
+        if (pDefKL)
+        {
+            pti->pClientInfo->hKL = pDefKL->hkl;
+            pKbdTbl = pDefKL->spkf->pKbdTbl;
+        }
+        else
+        {
+            pti->pClientInfo->hKL = NULL;
+            pKbdTbl = NULL;
+        }
     }
     else
        pKbdTbl = pti->KeyboardLayout->spkf->pKbdTbl;
diff --git a/win32ss/user/ntuser/main.c b/win32ss/user/ntuser/main.c
index 1010d7970ef..ea092317809 100644
--- a/win32ss/user/ntuser/main.c
+++ b/win32ss/user/ntuser/main.c
@@ -462,6 +462,7 @@ InitThreadCallback(PETHREAD Thread)
     NTSTATUS Status = STATUS_SUCCESS;
     PTEB pTeb;
     PRTL_USER_PROCESS_PARAMETERS ProcessParams;
+    PKL pDefKL;
     Process = Thread->ThreadsProcess;
@@ -532,9 +533,8 @@ InitThreadCallback(PETHREAD Thread)
         goto error;
     }
-    ptiCurrent->KeyboardLayout = W32kGetDefaultKeyLayout();
-    if (ptiCurrent->KeyboardLayout)
-        UserReferenceObject(ptiCurrent->KeyboardLayout);
+    pDefKL = W32kGetDefaultKeyLayout();
+    UserAssignmentLock((PVOID*)&(ptiCurrent->KeyboardLayout), pDefKL);
     ptiCurrent->TIF_flags &= ~TIF_INCLEANUP;
@@ -550,10 +550,10 @@ InitThreadCallback(PETHREAD Thread)
     pci->ppi = ptiCurrent->ppi;
     pci->fsHooks = ptiCurrent->fsHooks;
     pci->dwTIFlags = ptiCurrent->TIF_flags;
-    if (ptiCurrent->KeyboardLayout)
+    if (pDefKL)
     {
-        pci->hKL = ptiCurrent->KeyboardLayout->hkl;
-        pci->CodePage = ptiCurrent->KeyboardLayout->CodePage;
+        pci->hKL = pDefKL->hkl;
+        pci->CodePage = pDefKL->CodePage;
     }
     /* Need to pass the user Startup Information to the current process. */
@@ -829,8 +829,8 @@ ExitThreadCallback(PETHREAD Thread)
     /* Remove it from the list */
     *ppti = ptiCurrent->ptiSibling;
-    if (ptiCurrent->KeyboardLayout)
-        UserDereferenceObject(ptiCurrent->KeyboardLayout);
+    if (!UserAssignmentUnlock((PVOID*)&(ptiCurrent->KeyboardLayout)))
+        ptiCurrent->pClientInfo->hKL = NULL;
     if (gptiForeground == ptiCurrent)
     {