[NTUSER] KLF_UNLOAD flag of NtUserGetKeyboardLayoutList (#4592)

This implementation enables KLF_UNLOAD flag awareness on listing the KLs.
CORE-11700
This commit is contained in:
Katayama Hirofumi MZ 2022-08-03 12:45:10 +09:00 committed by GitHub
parent bfa92268da
commit 5f4db56486
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 40 deletions

View file

@ -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@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;
}
pKl = gspklBaseLayout;
if (nBuff == 0)
{
do
{
uRet++;
pKl = pKl->pklNext;
} while (pKl != gspklBaseLayout);
}
else
{
_SEH2_TRY
{
ProbeForWrite(pHklBuff, nBuff*sizeof(HKL), 4);
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;
SetLastNtError(ERROR_INVALID_PARAMETER);
goto Quit;
}
_SEH2_TRY
{
ProbeForWrite(pHklBuff, nBuff * sizeof(HKL), 1);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
SetLastNtError(_SEH2_GetExceptionCode());
goto Quit;
}
_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;
}
/*

View file

@ -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 ***********************************************************/

View file

@ -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);