[NTUSER] Improve NtUserDestroyInputContext etc. (#4442)

CORE-11700
This commit is contained in:
Katayama Hirofumi MZ 2022-04-10 12:27:38 +09:00 committed by GitHub
parent de38e3be61
commit eb902e5bee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

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