From 6c748ca8a9253d3e4241ec0bc945b16dec39e15e Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sat, 20 Aug 2022 09:45:06 +0900 Subject: [PATCH] [NTUSER] Rewrite NtUserUnloadKeyboardLayout (#4613) - Add co_IntUnloadKeyboardLayoutEx (Win: xxxInternalUnloadKeyboardLayout), IntUnloadKeyboardLayout (Win: xxxUnloadKeyboardLayout) helper functions. - Rewrite NtUserUnloadKeyboardLayout function. CORE-11700 --- win32ss/user/ntuser/kbdlayout.c | 75 +++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/win32ss/user/ntuser/kbdlayout.c b/win32ss/user/ntuser/kbdlayout.c index 90ad390cac4..fde11969f9b 100644 --- a/win32ss/user/ntuser/kbdlayout.c +++ b/win32ss/user/ntuser/kbdlayout.c @@ -23,6 +23,7 @@ PKL gspklBaseLayout = NULL; /* FIXME: Please move this to pWinSta->spklList */ PKBDFILE gpkfList = NULL; DWORD gSystemFS = 0; UINT gSystemCPCharSet = 0; +DWORD gLCIDSentToShell = 0; typedef PVOID (*PFN_KBDLAYERDESCRIPTOR)(VOID); @@ -774,6 +775,67 @@ co_IntActivateKeyboardLayout( return co_UserActivateKeyboardLayout(pKL, uFlags, pWnd); } +// Win: xxxInternalUnloadKeyboardLayout +static BOOL APIENTRY +co_IntUnloadKeyboardLayoutEx( + _Inout_ PWINSTATION_OBJECT pWinSta, + _Inout_ PKL pKL, + _In_ DWORD dwFlags) +{ + PKL pNextKL; + USER_REFERENCE_ENTRY Ref1, Ref2; + PTHREADINFO pti = gptiCurrent; + + if (pKL == gspklBaseLayout && !(dwFlags & 0x80000000)) + return FALSE; + + UserRefObjectCo(pKL, &Ref1); /* Add reference */ + + /* Regard as unloaded */ + UserMarkObjectDestroy(pKL); + pKL->dwKL_Flags |= KLF_UNLOAD; + + if (!(dwFlags & 0x80000000) && pti->KeyboardLayout == pKL) + { + pNextKL = IntHKLtoPKL(pti, (HKL)(ULONG_PTR)HKL_NEXT); + if (pNextKL) + { + UserRefObjectCo(pNextKL, &Ref2); /* Add reference */ + co_UserActivateKeyboardLayout(pNextKL, dwFlags, NULL); + UserDerefObjectCo(pNextKL); /* Release reference */ + } + } + + if (gspklBaseLayout == pKL && pKL != pKL->pklNext) + { + /* Set next layout as default (FIXME: Use UserAssignmentLock?) */ + gspklBaseLayout = pKL->pklNext; + } + + UserDerefObjectCo(pKL); /* Release reference */ + + if (pti->pDeskInfo->fsHooks) + { + co_IntShellHookNotify(HSHELL_LANGUAGE, 0, 0); + gLCIDSentToShell = 0; + } + + return TRUE; +} + +// Win: xxxUnloadKeyboardLayout +static BOOL APIENTRY +IntUnloadKeyboardLayout(_Inout_ PWINSTATION_OBJECT pWinSta, _In_ HKL hKL) +{ + PKL pKL = IntHKLtoPKL(gptiCurrent, hKL); + if (!pKL) + { + ERR("Invalid HKL %p!\n", hKL); + return FALSE; + } + return co_IntUnloadKeyboardLayoutEx(pWinSta, pKL, 0); +} + /* EXPORTS *******************************************************************/ /* @@ -1081,19 +1143,16 @@ APIENTRY NtUserUnloadKeyboardLayout( HKL hKl) { - PKL pKl; - BOOL bRet = FALSE; + BOOL ret; + PWINSTATION_OBJECT pWinSta; UserEnterExclusive(); - pKl = UserHklToKbl(hKl); - if (pKl) - bRet = UserUnloadKbl(pKl); - else - ERR("Invalid HKL %p!\n", hKl); + pWinSta = IntGetProcessWindowStation(NULL); + ret = IntUnloadKeyboardLayout(pWinSta, hKl); UserLeave(); - return bRet; + return ret; } /* EOF */