https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5f4db56486996351a742ec52385a0b604ebc9cd3

commit 5f4db56486996351a742ec52385a0b604ebc9cd3
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Wed Aug 3 12:45:10 2022 +0900
Commit:     GitHub <[email protected]>
CommitDate: Wed Aug 3 12:45:10 2022 +0900

    [NTUSER] KLF_UNLOAD flag of NtUserGetKeyboardLayoutList (#4592)
    
    This implementation enables KLF_UNLOAD flag awareness on listing the KLs.
    CORE-11700
---
 win32ss/user/ntuser/kbdlayout.c | 109 +++++++++++++++++++++++++++-------------
 win32ss/user/ntuser/winsta.c    |  12 +++++
 win32ss/user/ntuser/winsta.h    |   1 +
 3 files changed, 88 insertions(+), 34 deletions(-)

diff --git a/win32ss/user/ntuser/kbdlayout.c b/win32ss/user/ntuser/kbdlayout.c
index 82767e76388..bca41faef3b 100644
--- a/win32ss/user/ntuser/kbdlayout.c
+++ b/win32ss/user/ntuser/kbdlayout.c
@@ -6,6 +6,7 @@
  * COPYRIGHT:       Copyright 2007 Saveliy Tretiakov
  *                  Copyright 2008 Colin Finck
  *                  Copyright 2011 Rafal Harabien
+ *                  Copyright 2022 Katayama Hirofumi MZ 
<[email protected]>
  */
 
 #include <win32k.h>
@@ -17,16 +18,63 @@
 
 DBG_DEFAULT_CHANNEL(UserKbdLayout);
 
-PKL gspklBaseLayout = NULL;
+PKL gspklBaseLayout = NULL; /* FIXME: Please move this to pWinSta->spklList */
 PKBDFILE gpkfList = NULL;
 DWORD gSystemFS = 0;
 UINT gSystemCPCharSet = 0;
 
 typedef PVOID (*PFN_KBDLAYERDESCRIPTOR)(VOID);
 
-
 /* PRIVATE FUNCTIONS ******************************************************/
 
+// Win: _GetKeyboardLayoutList
+static UINT APIENTRY
+IntGetKeyboardLayoutList(
+    _Inout_ PWINSTATION_OBJECT pWinSta,
+    _In_ ULONG nBuff,
+    _Out_ HKL *pHklBuff)
+{
+    UINT ret = 0;
+    PKL pKL, pFirstKL;
+
+    pFirstKL = gspklBaseLayout; /* FIXME: Use pWinSta->spklList instead */
+    if (!pWinSta || !pFirstKL)
+        return 0;
+
+    pKL = pFirstKL;
+
+    if (nBuff == 0)
+    {
+        /* Count the effective PKLs */
+        do
+        {
+            if (!(pKL->dwKL_Flags & KLF_UNLOAD))
+                ++ret;
+            pKL = pKL->pklNext;
+        } while (pKL != pFirstKL);
+    }
+    else
+    {
+        /* Copy the effective HKLs to pHklBuff */
+        do
+        {
+            if (!(pKL->dwKL_Flags & KLF_UNLOAD))
+            {
+                *pHklBuff = pKL->hkl;
+                ++pHklBuff;
+                ++ret;
+                --nBuff;
+
+                if (nBuff == 0)
+                    break;
+            }
+            pKL = pKL->pklNext;
+        } while (pKL != pFirstKL);
+    }
+
+    return ret;
+}
+
 #if 0 && DBG
 
 static VOID
@@ -550,54 +598,47 @@ NtUserGetKeyboardLayoutList(
     ULONG nBuff,
     HKL *pHklBuff)
 {
-    UINT uRet = 0;
-    PKL pKl;
+    UINT ret = 0;
+    PWINSTATION_OBJECT pWinSta;
 
     if (!pHklBuff)
         nBuff = 0;
 
     UserEnterShared();
 
-    if (!gspklBaseLayout)
+    if (nBuff > MAXULONG / sizeof(HKL))
     {
-        UserLeave();
-        return 0;
+        SetLastNtError(ERROR_INVALID_PARAMETER);
+        goto Quit;
     }
-    pKl = gspklBaseLayout;
 
-    if (nBuff == 0)
+    _SEH2_TRY
     {
-        do
-        {
-            uRet++;
-            pKl = pKl->pklNext;
-        } while (pKl != gspklBaseLayout);
+        ProbeForWrite(pHklBuff, nBuff * sizeof(HKL), 1);
     }
-    else
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        _SEH2_TRY
-        {
-            ProbeForWrite(pHklBuff, nBuff*sizeof(HKL), 4);
+        SetLastNtError(_SEH2_GetExceptionCode());
+        goto Quit;
+    }
+    _SEH2_END;
 
-            while (uRet < nBuff)
-            {
-                pHklBuff[uRet] = pKl->hkl;
-                uRet++;
-                pKl = pKl->pklNext;
-                if (pKl == gspklBaseLayout)
-                    break;
-            }
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            SetLastNtError(_SEH2_GetExceptionCode());
-            uRet = 0;
-        }
-        _SEH2_END;
+    pWinSta = IntGetProcessWindowStation(NULL);
+
+    _SEH2_TRY
+    {
+        ret = IntGetKeyboardLayoutList(pWinSta, nBuff, pHklBuff);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        SetLastNtError(_SEH2_GetExceptionCode());
+        goto Quit;
     }
+    _SEH2_END;
 
+Quit:
     UserLeave();
-    return uRet;
+    return ret;
 }
 
 /*
diff --git a/win32ss/user/ntuser/winsta.c b/win32ss/user/ntuser/winsta.c
index 4c91558b497..b4c31dcf891 100644
--- a/win32ss/user/ntuser/winsta.c
+++ b/win32ss/user/ntuser/winsta.c
@@ -395,6 +395,18 @@ CheckWinstaAttributeAccess(ACCESS_MASK DesiredAccess)
     return TRUE;
 }
 
+// Win: _GetProcessWindowStation
+PWINSTATION_OBJECT FASTCALL
+IntGetProcessWindowStation(HWINSTA *phWinSta OPTIONAL)
+{
+    PWINSTATION_OBJECT pWinSta;
+    PPROCESSINFO ppi = GetW32ProcessInfo();
+    HWINSTA hWinSta = ppi->hwinsta;
+    if (phWinSta)
+        *phWinSta = hWinSta;
+    IntValidateWindowStationHandle(hWinSta, UserMode, 0, &pWinSta, 0);
+    return pWinSta;
+}
 
 /* PUBLIC FUNCTIONS 
***********************************************************/
 
diff --git a/win32ss/user/ntuser/winsta.h b/win32ss/user/ntuser/winsta.h
index 2918ca510fa..e755dad5bbf 100644
--- a/win32ss/user/ntuser/winsta.h
+++ b/win32ss/user/ntuser/winsta.h
@@ -106,6 +106,7 @@ IntCreateWindowStation(
     DWORD Unknown5,
     DWORD Unknown6);
 
+PWINSTATION_OBJECT FASTCALL IntGetProcessWindowStation(HWINSTA *phWinSta 
OPTIONAL);
 BOOL FASTCALL UserSetProcessWindowStation(HWINSTA hWindowStation);
 
 BOOL FASTCALL co_IntInitializeDesktopGraphics(VOID);

Reply via email to