https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5f4db56486996351a742e…
commit 5f4db56486996351a742ec52385a0b604ebc9cd3
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Wed Aug 3 12:45:10 2022 +0900
Commit: GitHub <noreply(a)github.com>
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
<katayama.hirofumi.mz(a)gmail.com>
*/
#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);