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

commit a8d2cd4b9d124bf9a9d97105cb11923827d7142b
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Tue Aug 24 06:50:39 2021 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Tue Aug 24 06:50:39 2021 +0900

    [IMM32] Rewrite ImmGetContext (#3923)
    
    - Add ValidateHwndNoErr and Imm32GetContextEx helper functions.
    - Rewrite ImmGetContext function by using the helper functions.
    CORE-11700
---
 dll/win32/imm32/imm.c    | 111 ++++++++++++++++++++++++++++++++---------------
 win32ss/include/ntuser.h |   1 +
 2 files changed, 78 insertions(+), 34 deletions(-)

diff --git a/dll/win32/imm32/imm.c b/dll/win32/imm32/imm.c
index 87097af5ad2..9f32bcc5d5d 100644
--- a/dll/win32/imm32/imm.c
+++ b/dll/win32/imm32/imm.c
@@ -61,6 +61,32 @@ SHAREDINFO g_SharedInfo = { NULL };
 BYTE g_bClientRegd = FALSE;
 HANDLE g_hImm32Heap = NULL;
 
+static PWND FASTCALL ValidateHwndNoErr(HWND hwnd)
+{
+    PCLIENTINFO ClientInfo = GetWin32ClientInfo();
+    INT index;
+    PUSER_HANDLE_TABLE ht;
+    WORD generation;
+
+    /* See if the window is cached */
+    if (hwnd == ClientInfo->CallbackWnd.hWnd)
+        return ClientInfo->CallbackWnd.pWnd;
+
+    if (!NtUserValidateHandleSecure(hwnd))
+        return NULL;
+
+    ht = g_SharedInfo.aheList; /* handle table */
+    index = (LOWORD(hwnd) - FIRST_USER_HANDLE) >> 1;
+    if (index < 0 || index >= ht->nb_handles || ht->handles[index].type != 
TYPE_WINDOW)
+        return NULL;
+
+    generation = HIWORD(hwnd);
+    if (generation != ht->handles[index].generation && generation && 
generation != 0xFFFF)
+        return NULL;
+
+    return (PWND)&ht->handles[index];
+}
+
 static BOOL APIENTRY Imm32InitInstance(HMODULE hMod)
 {
     NTSTATUS status;
@@ -120,6 +146,12 @@ static inline BOOL Imm32IsCrossThreadAccess(HIMC hIMC)
     return (dwImeThreadId != dwThreadId);
 }
 
+static BOOL Imm32IsCrossProcessAccess(HWND hWnd)
+{
+    return (NtUserQueryWindow(hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID) !=
+            (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess);
+}
+
 static VOID APIENTRY Imm32FreeImeDpi(PIMEDPI pImeDpi, BOOL bDestroy)
 {
     if (pImeDpi->hInst == NULL)
@@ -1862,6 +1894,40 @@ VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
     HeapFree(g_hImm32Heap, 0, pClientImc);
 }
 
+static HIMC APIENTRY Imm32GetContextEx(HWND hWnd, DWORD dwContextFlags)
+{
+    HIMC hIMC;
+    PCLIENTIMC pClientImc;
+    PWND pWnd;
+
+    if (!g_psi || !(g_psi->dwSRVIFlags & SRVINFO_IMM32))
+        return NULL;
+
+    if (!hWnd)
+    {
+        // FIXME: NtUserGetThreadState and enum ThreadStateRoutines are broken.
+        hIMC = (HIMC)NtUserGetThreadState(4);
+        goto Quit;
+    }
+
+    pWnd = ValidateHwndNoErr(hWnd);
+    if (!pWnd || Imm32IsCrossProcessAccess(hWnd))
+        return NULL;
+
+    hIMC = pWnd->hImc;
+    if (!hIMC && (dwContextFlags & 1))
+        hIMC = (HIMC)NtUserQueryWindow(hWnd, QUERY_WINDOW_DEFAULT_ICONTEXT);
+
+Quit:
+    pClientImc = ImmLockClientImc(hIMC);
+    if (pClientImc == NULL)
+        return NULL;
+    if ((dwContextFlags & 2) && (pClientImc->dwFlags & CLIENTIMC_UNKNOWN3))
+        hIMC = NULL;
+    ImmUnlockClientImc(pClientImc);
+    return hIMC;
+}
+
 static DWORD APIENTRY
 CandidateListWideToAnsi(const CANDIDATELIST *pWideCL, LPCANDIDATELIST pAnsiCL, 
DWORD dwBufLen,
                         UINT uCodePage)
@@ -2647,31 +2713,10 @@ BOOL WINAPI ImmGetCompositionWindow(HIMC hIMC, 
LPCOMPOSITIONFORM lpCompForm)
  */
 HIMC WINAPI ImmGetContext(HWND hWnd)
 {
-    HIMC rc;
-
-    TRACE("%p\n", hWnd);
-
-    if (!IsWindow(hWnd))
-    {
-        SetLastError(ERROR_INVALID_WINDOW_HANDLE);
+    TRACE("(%p)\n", hWnd);
+    if (hWnd == NULL)
         return NULL;
-    }
-
-    rc = GetPropW(hWnd,szwWineIMCProperty);
-    if (rc == (HIMC)-1)
-        rc = NULL;
-    else if (rc == NULL)
-        rc = get_default_context( hWnd );
-
-    if (rc)
-    {
-        InputContextData *data = (InputContextData *)rc;
-        data->IMC.hWnd = hWnd;
-    }
-
-    TRACE("returning %p\n", rc);
-
-    return rc;
+    return Imm32GetContextEx(hWnd, 2);
 }
 
 /***********************************************************************
@@ -2855,7 +2900,7 @@ UINT WINAPI ImmGetDescriptionA(
                               lpszDescription, uBufLen, NULL, NULL);
     if (uBufLen)
         lpszDescription[cch] = 0;
-    return cch;
+    return (UINT)cch;
 }
 
 /***********************************************************************
@@ -3632,13 +3677,10 @@ Quit:
  */
 BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)
 {
-  static BOOL shown = FALSE;
-
-  if (!shown) {
-     FIXME("(%p, %p): stub\n", hWnd, hIMC);
-     shown = TRUE;
-  }
-  return TRUE;
+    TRACE("(%p, %p)\n", hWnd, hIMC);
+    UNREFERENCED_PARAMETER(hWnd);
+    UNREFERENCED_PARAMETER(hIMC);
+    return TRUE; // Do nothing. This is correct.
 }
 
 /***********************************************************************
@@ -3698,7 +3740,7 @@ BOOL WINAPI ImmSetCandidateWindow(
     ImmUnlockIMC(hIMC);
 
     Imm32NotifyAction(hIMC, hWnd, NI_CONTEXTUPDATED, 0, IMC_SETCANDIDATEPOS,
-                      IMN_SETCANDIDATEPOS, (1 << lpCandidate->dwIndex));
+                      IMN_SETCANDIDATEPOS, (1 << (BYTE)lpCandidate->dwIndex));
     return TRUE;
 }
 
@@ -3721,7 +3763,7 @@ static VOID APIENTRY AnsiToWideLogFont(const LOGFONTA 
*plfA, LPLOGFONTW plfW)
     RtlCopyMemory(plfW, plfA, offsetof(LOGFONTW, lfFaceName));
     StringCchLengthA(plfA->lfFaceName, _countof(plfA->lfFaceName), &cchA);
     cchW = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, plfA->lfFaceName, 
(INT)cchA,
-                               plfW->lfFaceName, cchW);
+                               plfW->lfFaceName, (INT)cchW);
     if (cchW > _countof(plfW->lfFaceName) - 1)
         cchW = _countof(plfW->lfFaceName) - 1;
     plfW->lfFaceName[cchW] = 0;
@@ -5106,6 +5148,7 @@ Quit:
 UINT WINAPI ImmWINNLSGetIMEHotkey(HWND hwndIme)
 {
     TRACE("(%p)\n", hwndIme);
+    UNREFERENCED_PARAMETER(hwndIme);
     return 0; /* This is correct. This function of Windows just returns zero. 
*/
 }
 
diff --git a/win32ss/include/ntuser.h b/win32ss/include/ntuser.h
index f3777680be9..b94e9c8d3e3 100644
--- a/win32ss/include/ntuser.h
+++ b/win32ss/include/ntuser.h
@@ -1311,6 +1311,7 @@ C_ASSERT(sizeof(CLIENTIMC) == 0x34);
 /* flags for CLIENTIMC */
 #define CLIENTIMC_WIDE 0x1
 #define CLIENTIMC_UNKNOWN1 0x40
+#define CLIENTIMC_UNKNOWN3 0x80
 #define CLIENTIMC_UNKNOWN2 0x100
 
 DWORD

Reply via email to