From d5deacd90305a83d413af18dca8fa41fe03e61b3 Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sat, 1 Jan 2022 20:59:00 +0900 Subject: [PATCH] [NTUSER] Implement NtUserCreateInputContext (#4230) - Modify NtUserCreateInputContext prototype. - Add UserCreateInputContext helper function. - Implement NtUserCreateInputContext function by using UserCreateInputContext. - Call UserCreateInputContext(0) in InitThreadCallback function to create the default input context. CORE-11700 --- dll/win32/imm32/imm.c | 2 +- win32ss/include/ntuser.h | 2 +- win32ss/user/ntuser/main.c | 6 ++++ win32ss/user/ntuser/ntstubs.c | 57 +++++++++++++++++++++++++++++++-- win32ss/user/ntuser/userfuncs.h | 1 + 5 files changed, 63 insertions(+), 5 deletions(-) diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c index e24806c86d4..e916d44480f 100644 --- a/dll/win32/imm32/imm.c +++ b/dll/win32/imm32/imm.c @@ -597,7 +597,7 @@ HIMC WINAPI ImmCreateContext(void) if (pClientImc == NULL) return NULL; - hIMC = NtUserCreateInputContext(pClientImc); + hIMC = NtUserCreateInputContext((ULONG_PTR)pClientImc); if (hIMC == NULL) { Imm32HeapFree(pClientImc); diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h index 1e6234f84c1..4618c99af76 100644 --- a/win32ss/include/ntuser.h +++ b/win32ss/include/ntuser.h @@ -1937,7 +1937,7 @@ NtUserCreateDesktop( HIMC NTAPI -NtUserCreateInputContext(PCLIENTIMC pClientImc); +NtUserCreateInputContext(ULONG_PTR dwClientImcData); NTSTATUS NTAPI diff --git a/win32ss/user/ntuser/main.c b/win32ss/user/ntuser/main.c index 00a683af61c..8daf15ba95d 100644 --- a/win32ss/user/ntuser/main.c +++ b/win32ss/user/ntuser/main.c @@ -651,6 +651,12 @@ InitThreadCallback(PETHREAD Thread) } ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags; + /* Create the default input context */ + if (IS_IMM_MODE()) + { + UserCreateInputContext(0); + } + /* Last things to do only if we are not a SYSTEM or CSRSS thread */ if (!(ptiCurrent->TIF_flags & (TIF_SYSTEMTHREAD | TIF_CSRSSTHREAD))) { diff --git a/win32ss/user/ntuser/ntstubs.c b/win32ss/user/ntuser/ntstubs.c index 95a87900242..ddf9ba09381 100644 --- a/win32ss/user/ntuser/ntstubs.c +++ b/win32ss/user/ntuser/ntstubs.c @@ -461,12 +461,63 @@ NtUserYieldTask(VOID) return 0; } +PIMC FASTCALL UserCreateInputContext(ULONG_PTR dwClientImcData) +{ + PIMC pIMC; + PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); + PDESKTOP pdesk = pti->rpdesk; + + if (!IS_IMM_MODE() || (pti->TIF_flags & TIF_DISABLEIME)) // Disabled? + return NULL; + + if (!pdesk) // No desktop? + return NULL; + + // pti->spDefaultImc should be already set if non-first time. + if (dwClientImcData && !pti->spDefaultImc) + return NULL; + + // Create an input context user object. + pIMC = UserCreateObject(gHandleTable, pdesk, pti, NULL, TYPE_INPUTCONTEXT, sizeof(IMC)); + if (!pIMC) + return NULL; + + if (dwClientImcData) // Non-first time. + { + // Insert pIMC to the second position (non-default) of the list. + pIMC->pImcNext = pti->spDefaultImc->pImcNext; + pti->spDefaultImc->pImcNext = pIMC; + } + else // First time. It's the default IMC. + { + // Add the first one (default) to the list. + pti->spDefaultImc = pIMC; + pIMC->pImcNext = NULL; + } + + pIMC->dwClientImcData = dwClientImcData; // Set it. + return pIMC; +} + HIMC APIENTRY -NtUserCreateInputContext(PCLIENTIMC pClientImc) +NtUserCreateInputContext(ULONG_PTR dwClientImcData) { - STUB; - return NULL; + PIMC pIMC; + HIMC ret = NULL; + + UserEnterExclusive(); + + if (!IS_IMM_MODE() || !dwClientImcData) + goto Quit; + + pIMC = UserCreateInputContext(dwClientImcData); + if (pIMC) + ret = UserHMGetHandle(pIMC); + +Quit: + UserLeave(); + return ret; } DWORD diff --git a/win32ss/user/ntuser/userfuncs.h b/win32ss/user/ntuser/userfuncs.h index 6fb86e64d71..3bae17d5567 100644 --- a/win32ss/user/ntuser/userfuncs.h +++ b/win32ss/user/ntuser/userfuncs.h @@ -165,6 +165,7 @@ BOOL FASTCALL GetLayeredStatus(PWND pWnd); /************** INPUT CONTEXT **************/ +PIMC FASTCALL UserCreateInputContext(ULONG_PTR dwClientImcData); VOID UserFreeInputContext(PVOID Object); BOOLEAN UserDestroyInputContext(PVOID Object); PVOID AllocInputContextObject(PDESKTOP pDesk, PTHREADINFO pti, SIZE_T Size, PVOID* HandleOwner);