From: Katayama Hirofumi MZ Date: Wed, 3 Aug 2022 03:45:10 +0000 (+0900) Subject: [NTUSER] KLF_UNLOAD flag of NtUserGetKeyboardLayoutList (#4592) X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=5f4db56486996351a742ec52385a0b604ebc9cd3 [NTUSER] KLF_UNLOAD flag of NtUserGetKeyboardLayoutList (#4592) This implementation enables KLF_UNLOAD flag awareness on listing the KLs. CORE-11700 --- 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 */ #include @@ -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);