https://git.reactos.org/?p=reactos.git;a=commitdiff;h=89cb8a38b3b116a12b16d81b72a6255474e2fc77

commit 89cb8a38b3b116a12b16d81b72a6255474e2fc77
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Sat Jul 31 15:45:07 2021 +0900
Commit:     GitHub <[email protected]>
CommitDate: Sat Jul 31 15:45:07 2021 +0900

    [IMM32] Rewrite ImmEnumInputContext (#3859)
    
    - Rewrite ImmEnumInputContext function.
    - Modify NtUserBuildHimcList.
    CORE-11700
---
 dll/win32/imm32/imm.c         | 68 +++++++++++++++++++++++++++++++++++++++++--
 win32ss/include/ntuser.h      |  8 ++---
 win32ss/user/ntuser/ntstubs.c | 10 ++-----
 3 files changed, 70 insertions(+), 16 deletions(-)

diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c
index 2f316db2a08..5e655e6c4e6 100644
--- a/dll/win32/imm32/imm.c
+++ b/dll/win32/imm32/imm.c
@@ -1161,6 +1161,50 @@ static PCLIENTIMC APIENTRY Imm32GetClientImcCache(void)
     return NULL;
 }
 
+static NTSTATUS APIENTRY
+Imm32BuildHimcList(DWORD dwThreadId, DWORD dwCount, HIMC *phList, LPDWORD 
pdwCount)
+{
+    return NtUserBuildHimcList(dwThreadId, dwCount, phList, pdwCount);
+}
+
+static DWORD APIENTRY Imm32AllocAndBuildHimcList(DWORD dwThreadId, HIMC 
**pphList)
+{
+#define INITIAL_COUNT 0x40
+#define MAX_RETRY 10
+    NTSTATUS Status;
+    DWORD dwCount = INITIAL_COUNT, cRetry = 0;
+    HIMC *phNewList;
+
+    phNewList = Imm32HeapAlloc(0, dwCount * sizeof(HIMC));
+    if (phNewList == NULL)
+        return 0;
+
+    Status = Imm32BuildHimcList(dwThreadId, dwCount, phNewList, &dwCount);
+    while (Status == STATUS_BUFFER_TOO_SMALL)
+    {
+        HeapFree(g_hImm32Heap, 0, phNewList);
+        if (cRetry++ >= MAX_RETRY)
+            return 0;
+
+        phNewList = Imm32HeapAlloc(0, dwCount * sizeof(HIMC));
+        if (phNewList == NULL)
+            return 0;
+
+        Status = Imm32BuildHimcList(dwThreadId, dwCount, phNewList, &dwCount);
+    }
+
+    if (NT_ERROR(Status) || !dwCount)
+    {
+        HeapFree(g_hImm32Heap, 0, phNewList);
+        return 0;
+    }
+
+    *pphList = phNewList;
+    return dwCount;
+#undef INITIAL_COUNT
+#undef MAX_RETRY
+}
+
 PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
 {
     PCLIENTIMC pClientImc;
@@ -3735,11 +3779,29 @@ BOOL WINAPI ImmDisableTextFrameService(DWORD dwThreadId)
 /***********************************************************************
  *              ImmEnumInputContext(IMM32.@)
  */
-
 BOOL WINAPI ImmEnumInputContext(DWORD dwThreadId, IMCENUMPROC lpfn, LPARAM 
lParam)
 {
-    FIXME("Stub\n");
-    return FALSE;
+    HIMC *phList;
+    DWORD dwIndex, dwCount;
+    BOOL ret = TRUE;
+    HIMC hIMC;
+
+    TRACE("ImmEnumInputContext(%lu, %p, %p)\n", dwThreadId, lpfn, lParam);
+
+    dwCount = Imm32AllocAndBuildHimcList(dwThreadId, &phList);
+    if (!dwCount)
+        return FALSE;
+
+    for (dwIndex = 0; dwIndex < dwCount; ++dwIndex)
+    {
+        hIMC = phList[dwIndex];
+        ret = (*lpfn)(hIMC, lParam);
+        if (!ret)
+            break;
+    }
+
+    HeapFree(g_hImm32Heap, 0, phList);
+    return ret;
 }
 
 /***********************************************************************
diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h
index 7c30a21d54d..8182efe16f3 100644
--- a/win32ss/include/ntuser.h
+++ b/win32ss/include/ntuser.h
@@ -1253,13 +1253,9 @@ NtUserAssociateInputContext(
     DWORD dwUnknown2,
     DWORD dwUnknown3);
 
-DWORD
+NTSTATUS
 NTAPI
-NtUserBuildHimcList(
-    DWORD dwUnknown1,
-    DWORD dwUnknown2,
-    DWORD dwUnknown3,
-    DWORD dwUnknown4);
+NtUserBuildHimcList(DWORD dwThreadId, DWORD dwCount, HIMC *phList, LPDWORD 
pdwCount);
 
 DWORD
 NTAPI
diff --git a/win32ss/user/ntuser/ntstubs.c b/win32ss/user/ntuser/ntstubs.c
index 5ebde8bb41c..9ee6b4f8a39 100644
--- a/win32ss/user/ntuser/ntstubs.c
+++ b/win32ss/user/ntuser/ntstubs.c
@@ -54,16 +54,12 @@ NtUserBitBltSysBmp(
    return Ret;
 }
 
-DWORD
+NTSTATUS
 APIENTRY
-NtUserBuildHimcList(
-    DWORD dwUnknown1,
-    DWORD dwUnknown2,
-    DWORD dwUnknown3,
-    DWORD dwUnknown4)
+NtUserBuildHimcList(DWORD dwThreadId, DWORD dwCount, HIMC *phList, LPDWORD 
pdwCount)
 {
     STUB;
-    return 0;
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 DWORD

Reply via email to