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

commit eb902e5bee0077d438a2dfb10f391132b18bab67
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Sun Apr 10 12:27:38 2022 +0900
Commit:     GitHub <[email protected]>
CommitDate: Sun Apr 10 12:27:38 2022 +0900

    [NTUSER] Improve NtUserDestroyInputContext etc. (#4442)
    
    CORE-11700
---
 win32ss/user/ntuser/ime.c | 81 ++++++++++++++++++++++++++---------------------
 1 file changed, 45 insertions(+), 36 deletions(-)

diff --git a/win32ss/user/ntuser/ime.c b/win32ss/user/ntuser/ime.c
index c6f5473d8d9..1aa1ce49dd8 100644
--- a/win32ss/user/ntuser/ime.c
+++ b/win32ss/user/ntuser/ime.c
@@ -1231,19 +1231,19 @@ VOID UserFreeInputContext(PVOID Object)
 {
     PTHRDESKHEAD ObjHead = Object;
     PDESKTOP pDesk = ObjHead->rpdesk;
-    PIMC pIMC = Object, *ppIMC;
+    PIMC pNode, pIMC = Object;
     PTHREADINFO pti;
 
     if (!pIMC)
         return;
 
-    /* Find the IMC in the list and remove it */
+    // Remove pIMC from the list except spDefaultImc
     pti = pIMC->head.pti;
-    for (ppIMC = &pti->spDefaultImc; *ppIMC; ppIMC = &(*ppIMC)->pImcNext)
+    for (pNode = pti->spDefaultImc; pNode; pNode = pNode->pImcNext)
     {
-        if (*ppIMC == pIMC)
+        if (pNode->pImcNext == pIMC)
         {
-            *ppIMC = pIMC->pImcNext;
+            pNode->pImcNext = pIMC->pImcNext;
             break;
         }
     }
@@ -1258,60 +1258,69 @@ BOOLEAN UserDestroyInputContext(PVOID Object)
 {
     PIMC pIMC = Object;
 
-    if (!pIMC)
+    if (!pIMC || !UserMarkObjectDestroy(pIMC))
         return TRUE;
 
-    UserMarkObjectDestroy(pIMC);
-
     return UserDeleteObject(UserHMGetHandle(pIMC), TYPE_INPUTCONTEXT);
 }
 
-BOOL NTAPI NtUserDestroyInputContext(HIMC hIMC)
+// Win: DestroyInputContext
+BOOLEAN IntDestroyInputContext(PVOID Object)
 {
-    PIMC pIMC;
-    BOOL ret = FALSE;
+    PIMC pIMC = Object;
+    HIMC hIMC = pIMC->head.h;
+    PTHREADINFO pti = pIMC->head.pti;
+    PWND pwndChild;
+    PWINDOWLIST pwl;
     HWND *phwnd;
     PWND pWnd;
-    PWINDOWLIST pwl;
-    PTHREADINFO pti;
 
-    UserEnterExclusive();
-
-    if (!IS_IMM_MODE())
+    if (pIMC->head.pti != gptiCurrent)
     {
-        ERR("!IS_IMM_MODE()\n");
-        EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-        goto Quit;
+        EngSetLastError(ERROR_ACCESS_DENIED);
+        return FALSE;
     }
 
-    pIMC = UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT);
-    if (!pIMC)
-        goto Quit;
-
-    pti = pIMC->head.pti;
-    if (pti != GetW32ThreadInfo() || pIMC == pti->spDefaultImc)
-        goto Quit;
-
-    UserMarkObjectDestroy(pIMC);
+    if (pIMC == pti->spDefaultImc)
+    {
+        EngSetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
 
-    pwl = IntBuildHwndList(pti->rpdesk->pDeskInfo->spwnd->spwndChild,
-                           IACE_CHILDREN | IACE_LIST, pti);
+    pwndChild = pti->rpdesk->pDeskInfo->spwnd->spwndChild;
+    pwl = IntBuildHwndList(pwndChild, IACE_LIST | IACE_CHILDREN, pti);
     if (pwl)
     {
         for (phwnd = pwl->ahwnd; *phwnd != HWND_TERMINATOR; ++phwnd)
         {
-            pWnd = ValidateHwndNoErr(*phwnd);
-            if (!pWnd)
-                continue;
-
-            if (pWnd->hImc == hIMC)
+            pWnd = UserGetObjectNoErr(gHandleTable, *phwnd, TYPE_WINDOW);
+            if (pWnd && pWnd->hImc == hIMC)
                 IntAssociateInputContext(pWnd, pti->spDefaultImc);
         }
 
         IntFreeHwndList(pwl);
     }
 
-    ret = UserDeleteObject(hIMC, TYPE_INPUTCONTEXT);
+    UserDeleteObject(hIMC, TYPE_INPUTCONTEXT);
+    return TRUE;
+}
+
+BOOL NTAPI NtUserDestroyInputContext(HIMC hIMC)
+{
+    BOOL ret = FALSE;
+    PIMC pIMC;
+
+    UserEnterExclusive();
+
+    if (!IS_IMM_MODE())
+    {
+        EngSetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+        goto Quit;
+    }
+
+    pIMC = UserGetObjectNoErr(gHandleTable, hIMC, TYPE_INPUTCONTEXT);
+    if (pIMC)
+        ret = IntDestroyInputContext(pIMC);
 
 Quit:
     UserLeave();

Reply via email to