https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d5deacd90305a83d413af…
commit d5deacd90305a83d413af18dca8fa41fe03e61b3
Author:     Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Jan 1 20:59:00 2022 +0900
Commit:     GitHub <noreply(a)github.com>
CommitDate: Sat Jan 1 20:59:00 2022 +0900
    [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);