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

commit aa8fc872a098d261e13e48aeb32fb85808e36d1d
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Sun Oct 17 19:32:48 2021 +0900
Commit:     GitHub <[email protected]>
CommitDate: Sun Oct 17 19:32:48 2021 +0900

    [IMM32][IMM32_WINETEST] Re-implement ImmSetCompositionStringA/W (#4040)
    
    - Modify ImmSetCompositionStringA and ImmSetCompositionStringW prototypes 
(removing const of two arguments).
    - Add Imm32OpenICAndCS helper function.
    - Implement Imm32SetCompositionStringAW function.
    - Modify imm32_winetest (due to removal of const).
    CORE-11700
---
 dll/win32/imm32/compstr.c                | 372 ++++++++++++++++++++++++++++++-
 modules/rostests/winetests/imm32/imm32.c |   8 +
 sdk/include/psdk/imm.h                   |   8 +-
 3 files changed, 372 insertions(+), 16 deletions(-)

diff --git a/dll/win32/imm32/compstr.c b/dll/win32/imm32/compstr.c
index df0726c2fa2..7fa9a0e4111 100644
--- a/dll/win32/imm32/compstr.c
+++ b/dll/win32/imm32/compstr.c
@@ -14,12 +14,37 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(imm);
 
+BOOL APIENTRY
+Imm32OpenICAndCS(HIMC hIMC, LPINPUTCONTEXT *ppIC, LPCOMPOSITIONSTRING *ppCS)
+{
+    LPINPUTCONTEXT pIC;
+    LPCOMPOSITIONSTRING pCS;
+
+    *ppIC = NULL;
+    *ppCS = NULL;
+
+    pIC = ImmLockIMC(hIMC);
+    if (!pIC)
+        return FALSE;
+
+    pCS = ImmLockIMCC(pIC->hCompStr);
+    if (!pCS)
+    {
+        ImmUnlockIMC(hIMC);
+        return FALSE;
+    }
+
+    *ppIC = pIC;
+    *ppCS = pCS;
+    return TRUE;
+}
+
 static inline LONG APIENTRY
 Imm32CompStrAnsiToWide(LPCSTR psz, DWORD cb, LPWSTR lpBuf, DWORD dwBufLen, 
UINT uCodePage)
 {
     DWORD ret = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, psz, cb / 
sizeof(CHAR),
                                     lpBuf, dwBufLen / sizeof(WCHAR));
-    if ((ret + 1) * sizeof(WCHAR) <= dwBufLen)
+    if (lpBuf && (ret + 1) * sizeof(WCHAR) <= dwBufLen)
         lpBuf[ret] = 0;
     return ret * sizeof(WCHAR);
 }
@@ -29,7 +54,7 @@ Imm32CompStrWideToAnsi(LPCWSTR psz, DWORD cb, LPSTR lpBuf, 
DWORD dwBufLen, UINT
 {
     DWORD ret = WideCharToMultiByte(uCodePage, 0, psz, cb / sizeof(WCHAR),
                                     lpBuf, dwBufLen / sizeof(CHAR), NULL, 
NULL);
-    if ((ret + 1) * sizeof(CHAR) <= dwBufLen)
+    if (lpBuf && (ret + 1) * sizeof(CHAR) <= dwBufLen)
         lpBuf[ret] = 0;
     return ret * sizeof(CHAR);
 }
@@ -44,6 +69,7 @@ Imm32CompAttrWideToAnsi(const BYTE *src, INT src_len, LPCWSTR 
text,
     if (!src_len)
         return 0;
 
+    str_len /= sizeof(WCHAR);
     rc = WideCharToMultiByte(uCodePage, 0, text, str_len, NULL, 0, NULL, NULL);
 
     if (dst_len)
@@ -66,7 +92,7 @@ end:
         rc = j;
     }
 
-    return rc;
+    return rc * sizeof(BYTE);
 }
 
 static INT APIENTRY
@@ -79,6 +105,7 @@ Imm32CompAttrAnsiToWide(const BYTE *src, INT src_len, LPCSTR 
text,
     if (!src_len)
         return 0;
 
+    str_len /= sizeof(CHAR);
     rc = MultiByteToWideChar(uCodePage, MB_PRECOMPOSED, text, str_len, NULL, 
0);
 
     if (dst_len)
@@ -100,7 +127,7 @@ Imm32CompAttrAnsiToWide(const BYTE *src, INT src_len, 
LPCSTR text,
         rc = j;
     }
 
-    return rc;
+    return rc * sizeof(BYTE);
 }
 
 static INT APIENTRY
@@ -487,11 +514,332 @@ Imm32GetCompStrW(HIMC hIMC, const COMPOSITIONSTRING 
*pCS, DWORD dwIndex,
 }
 
 BOOL APIENTRY
-Imm32SetCompositionStringAW(HIMC hIMC, DWORD dwIndex, LPCVOID lpComp, DWORD 
dwCompLen,
-                            LPCVOID lpRead, DWORD dwReadLen, BOOL bAnsi)
+Imm32SetCompositionStringAW(HIMC hIMC, DWORD dwIndex, LPVOID pComp, DWORD 
dwCompLen,
+                            LPVOID pRead, DWORD dwReadLen, BOOL bAnsiAPI)
 {
-    FIXME("TODO:\n");
-    return FALSE;
+    BOOL ret = FALSE, bAnsiClient;
+    LPVOID pCompNew = NULL, pReadNew = NULL;
+    DWORD dwThreadId, cbCompNew = 0, cbReadNew = 0;
+    LPINPUTCONTEXT pIC;
+    LPCOMPOSITIONSTRING pCS;
+    HKL hKL;
+    PIMEDPI pImeDpi;
+    UINT uCodePage;
+    LPRECONVERTSTRING pRS;
+
+    dwThreadId = NtUserQueryInputContext(hIMC, 1);
+    if (dwThreadId != GetCurrentThreadId())
+        return FALSE;
+
+    hKL = GetKeyboardLayout(dwThreadId);
+    pImeDpi = ImmLockImeDpi(hKL);
+    if (!pImeDpi)
+        return FALSE;
+
+    uCodePage = pImeDpi->uCodePage;
+    bAnsiClient = !ImeDpi_IsUnicode(pImeDpi);
+
+    switch (dwIndex)
+    {
+        case SCS_SETSTR: case SCS_CHANGEATTR: case SCS_CHANGECLAUSE:
+            break;
+
+        case SCS_SETRECONVERTSTRING: case SCS_QUERYRECONVERTSTRING:
+            if (pImeDpi->ImeInfo.fdwSCSCaps & SCS_CAP_SETRECONVERTSTRING)
+                break;
+            /* FALL THROUGH */
+        default:
+            ImmUnlockImeDpi(pImeDpi);
+            return FALSE;
+    }
+
+    if (bAnsiAPI == bAnsiClient || (!pComp && !pRead))
+    {
+        ret = pImeDpi->ImeSetCompositionString(hIMC, dwIndex, pComp, dwCompLen,
+                                               pRead, dwReadLen);
+        ImmUnlockImeDpi(pImeDpi);
+        return ret;
+    }
+
+    if (!Imm32OpenICAndCS(hIMC, &pIC, &pCS))
+    {
+        ImmUnlockImeDpi(pImeDpi);
+        return FALSE;
+    }
+
+    /*
+     * This code is really too complicated. But I cannot simplify.
+     * It converts like (pComp, dwCompLen) --> (pCompNew, cbCompNew) and
+     * (pRead, dwReadLen) --> (pReadNew, cbReadNew).
+     * (1) Check bAnsiClient, (2) Get the size, (3) Allocate a buffer for 
conversion,
+     * (4) Store converted data into the buffer.
+     */
+    switch (dwIndex)
+    {
+        case SCS_SETSTR:
+            if (pComp)
+            {
+                if (bAnsiClient)
+                {
+                    cbCompNew = Imm32CompStrWideToAnsi(pComp, dwCompLen, NULL, 
0, uCodePage);
+                    pCompNew = Imm32HeapAlloc(0, cbCompNew);
+                    if (!pCompNew)
+                        goto Quit;
+
+                    Imm32CompStrWideToAnsi(pComp, dwCompLen, pCompNew, 
cbCompNew, uCodePage);
+                }
+                else
+                {
+                    cbCompNew = Imm32CompStrAnsiToWide(pComp, dwCompLen, NULL, 
0, uCodePage);
+                    pCompNew = Imm32HeapAlloc(0, cbCompNew);
+                    if (!pCompNew)
+                        goto Quit;
+
+                    Imm32CompStrAnsiToWide(pComp, dwCompLen, pCompNew, 
cbCompNew, uCodePage);
+                }
+            }
+
+            if (pRead)
+            {
+                if (bAnsiClient)
+                {
+                    cbReadNew = Imm32CompStrWideToAnsi(pRead, dwReadLen, NULL, 
0, uCodePage);
+                    pReadNew = Imm32HeapAlloc(0, cbReadNew);
+                    if (!pReadNew)
+                        goto Quit;
+
+                    Imm32CompStrWideToAnsi(pRead, dwReadLen, pReadNew, 
cbReadNew, uCodePage);
+                }
+                else
+                {
+                    cbReadNew = Imm32CompStrAnsiToWide(pRead, dwReadLen, NULL, 
0, uCodePage);
+                    pReadNew = Imm32HeapAlloc(0, cbReadNew);
+                    if (!pReadNew)
+                        goto Quit;
+
+                    Imm32CompStrAnsiToWide(pRead, dwReadLen, pReadNew, 
cbReadNew, uCodePage);
+                }
+            }
+            break;
+
+        case SCS_CHANGEATTR:
+            if (pComp)
+            {
+                if (bAnsiClient)
+                {
+                    cbCompNew = Imm32CompAttrWideToAnsi(pComp, dwCompLen,
+                                                        CS_StrW(pCS, CompStr),
+                                                        CS_SizeW(pCS, CompStr),
+                                                        NULL, 0, uCodePage);
+                    pCompNew = Imm32HeapAlloc(0, cbCompNew);
+                    if (!pCompNew)
+                        goto Quit;
+
+                    Imm32CompAttrWideToAnsi(pComp, dwCompLen,
+                                            CS_StrW(pCS, CompStr), 
CS_SizeW(pCS, CompStr),
+                                            pCompNew, cbCompNew, uCodePage);
+                }
+                else
+                {
+                    cbCompNew = Imm32CompAttrAnsiToWide(pComp, dwCompLen,
+                                                        CS_StrA(pCS, CompStr),
+                                                        CS_SizeA(pCS, CompStr),
+                                                        NULL, 0, uCodePage);
+                    pCompNew = Imm32HeapAlloc(0, cbCompNew);
+                    if (!pCompNew)
+                        goto Quit;
+
+                    Imm32CompAttrAnsiToWide(pComp, dwCompLen,
+                                            CS_StrA(pCS, CompStr), 
CS_SizeA(pCS, CompStr),
+                                            pCompNew, cbCompNew, uCodePage);
+                }
+            }
+
+            if (pRead)
+            {
+                if (bAnsiClient)
+                {
+                    cbReadNew = Imm32CompAttrWideToAnsi(pRead, dwReadLen,
+                                                        CS_StrW(pCS, 
CompReadStr),
+                                                        CS_SizeW(pCS, 
CompReadStr),
+                                                        NULL, 0, uCodePage);
+                    pReadNew = Imm32HeapAlloc(0, cbReadNew);
+                    if (!pReadNew)
+                        goto Quit;
+
+                    Imm32CompAttrWideToAnsi(pRead, dwReadLen,
+                                            CS_StrW(pCS, CompReadStr), 
CS_SizeW(pCS, CompReadStr),
+                                            pReadNew, cbReadNew, uCodePage);
+                }
+                else
+                {
+                    cbReadNew = Imm32CompAttrAnsiToWide(pRead, dwReadLen,
+                                                        CS_StrA(pCS, 
CompReadStr),
+                                                        CS_SizeA(pCS, 
CompReadStr),
+                                                        NULL, 0, uCodePage);
+                    pReadNew = Imm32HeapAlloc(0, cbReadNew);
+                    if (!pReadNew)
+                        goto Quit;
+
+                    Imm32CompAttrAnsiToWide(pRead, dwReadLen,
+                                            CS_StrA(pCS, CompReadStr), 
CS_SizeA(pCS, CompReadStr),
+                                            pReadNew, cbReadNew, uCodePage);
+                }
+            }
+            break;
+
+        case SCS_CHANGECLAUSE:
+            if (pComp)
+            {
+                if (bAnsiClient)
+                {
+                    cbCompNew = Imm32CompClauseWideToAnsi(pComp, dwCompLen, 
CS_StrW(pCS, CompStr),
+                                                          NULL, 0, uCodePage);
+                    pCompNew = Imm32HeapAlloc(0, cbCompNew);
+                    if (!pCompNew)
+                        goto Quit;
+
+                    Imm32CompClauseWideToAnsi(pComp, dwCompLen, CS_StrW(pCS, 
CompStr),
+                                              pCompNew, cbCompNew, uCodePage);
+                }
+                else
+                {
+                    cbCompNew = Imm32CompClauseAnsiToWide(pComp, dwCompLen, 
CS_StrA(pCS, CompStr),
+                                                          NULL, 0, uCodePage);
+                    pCompNew = Imm32HeapAlloc(0, cbCompNew);
+                    if (!pCompNew)
+                        goto Quit;
+
+                    Imm32CompClauseAnsiToWide(pComp, dwCompLen, CS_StrA(pCS, 
CompStr),
+                                              pCompNew, cbCompNew, uCodePage);
+                }
+            }
+
+            if (pRead)
+            {
+                if (bAnsiClient)
+                {
+                    cbReadNew = Imm32CompClauseWideToAnsi(pRead, dwReadLen, 
CS_StrW(pCS, CompReadStr),
+                                                          NULL, 0, uCodePage);
+                    pReadNew = Imm32HeapAlloc(0, cbReadNew);
+                    if (!pReadNew)
+                        goto Quit;
+
+                    Imm32CompClauseWideToAnsi(pRead, dwReadLen,
+                                              CS_StrW(pCS, CompReadStr),
+                                              pReadNew, cbReadNew, uCodePage);
+                }
+                else
+                {
+                    cbReadNew = Imm32CompClauseAnsiToWide(pRead, dwReadLen, 
CS_StrA(pCS, CompReadStr),
+                                                          NULL, 0, uCodePage);
+                    pReadNew = Imm32HeapAlloc(0, cbReadNew);
+                    if (!pReadNew)
+                        goto Quit;
+
+                    Imm32CompClauseAnsiToWide(pRead, dwReadLen, CS_StrA(pCS, 
CompReadStr),
+                                              pReadNew, cbReadNew, uCodePage);
+                }
+            }
+            break;
+
+        case SCS_SETRECONVERTSTRING: case SCS_QUERYRECONVERTSTRING:
+        {
+            if (pComp)
+            {
+                if (bAnsiClient)
+                {
+                    cbCompNew = Imm32ReconvertAnsiFromWide(NULL, pComp, 
uCodePage);
+                    pCompNew = Imm32HeapAlloc(0, cbCompNew);
+                    if (!pCompNew)
+                        goto Quit;
+
+                    pRS = pCompNew;
+                    pRS->dwSize = cbCompNew;
+                    pRS->dwVersion = 0;
+                    Imm32ReconvertAnsiFromWide(pRS, pComp, uCodePage);
+                }
+                else
+                {
+                    cbCompNew = Imm32ReconvertWideFromAnsi(NULL, pComp, 
uCodePage);
+                    pCompNew = Imm32HeapAlloc(0, cbCompNew);
+                    if (!pCompNew)
+                        goto Quit;
+
+                    pRS = pCompNew;
+                    pRS->dwSize = cbCompNew;
+                    pRS->dwVersion = 0;
+                    Imm32ReconvertWideFromAnsi(pRS, pComp, uCodePage);
+                }
+            }
+
+            if (pRead)
+            {
+                if (bAnsiClient)
+                {
+                    cbReadNew = Imm32ReconvertAnsiFromWide(NULL, pRead, 
uCodePage);
+                    pReadNew = Imm32HeapAlloc(0, cbReadNew);
+                    if (!pReadNew)
+                        goto Quit;
+
+                    pRS = pReadNew;
+                    pRS->dwSize = cbReadNew;
+                    pRS->dwVersion = 0;
+                    Imm32ReconvertAnsiFromWide(pRS, pRead, uCodePage);
+                }
+                else
+                {
+                    cbReadNew = Imm32ReconvertWideFromAnsi(NULL, pRead, 
uCodePage);
+                    pReadNew = Imm32HeapAlloc(0, cbReadNew);
+                    if (!pReadNew)
+                        goto Quit;
+
+                    pRS = pReadNew;
+                    pRS->dwSize = cbReadNew;
+                    pRS->dwVersion = 0;
+                    Imm32ReconvertWideFromAnsi(pRS, pRead, uCodePage);
+                }
+            }
+            break;
+        }
+    }
+
+    ImmUnlockIMCC(pIC->hCompStr);
+    pCS = NULL;
+    ImmUnlockIMC(hIMC);
+    pIC = NULL;
+
+    ret = pImeDpi->ImeSetCompositionString(hIMC, dwIndex, pCompNew, cbCompNew,
+                                           pReadNew, cbReadNew);
+
+    if (dwIndex == SCS_QUERYRECONVERTSTRING)
+    {
+        if (pComp)
+        {
+            if (bAnsiClient)
+                ret = Imm32ReconvertWideFromAnsi(pComp, pCompNew, uCodePage);
+            else
+                ret = Imm32ReconvertAnsiFromWide(pComp, pCompNew, uCodePage);
+        }
+
+        if (pRead)
+        {
+            if (bAnsiClient)
+                ret = Imm32ReconvertWideFromAnsi(pRead, pReadNew, uCodePage);
+            else
+                ret = Imm32ReconvertAnsiFromWide(pRead, pReadNew, uCodePage);
+        }
+    }
+
+Quit:
+    if (pCS)
+        ImmUnlockIMCC(pIC->hCompStr);
+    if (pIC)
+        ImmUnlockIMC(hIMC);
+    Imm32HeapFree(pCompNew);
+    Imm32HeapFree(pReadNew);
+    ImmUnlockImeDpi(pImeDpi);
+    return ret;
 }
 
 /***********************************************************************
@@ -582,8 +930,8 @@ LONG WINAPI ImmGetCompositionStringW(HIMC hIMC, DWORD 
dwIndex, LPVOID lpBuf, DWO
  *             ImmSetCompositionStringA (IMM32.@)
  */
 BOOL WINAPI
-ImmSetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPCVOID lpComp, DWORD 
dwCompLen,
-                         LPCVOID lpRead, DWORD dwReadLen)
+ImmSetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPVOID lpComp, DWORD 
dwCompLen,
+                         LPVOID lpRead, DWORD dwReadLen)
 {
     TRACE("(%p, %lu, %p, %lu, %p, %lu)\n",
           hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
@@ -595,8 +943,8 @@ ImmSetCompositionStringA(HIMC hIMC, DWORD dwIndex, LPCVOID 
lpComp, DWORD dwCompL
  *             ImmSetCompositionStringW (IMM32.@)
  */
 BOOL WINAPI
-ImmSetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPCVOID lpComp, DWORD 
dwCompLen,
-                         LPCVOID lpRead, DWORD dwReadLen)
+ImmSetCompositionStringW(HIMC hIMC, DWORD dwIndex, LPVOID lpComp, DWORD 
dwCompLen,
+                         LPVOID lpRead, DWORD dwReadLen)
 {
     TRACE("(%p, %lu, %p, %lu, %p, %lu)\n",
           hIMC, dwIndex, lpComp, dwCompLen, lpRead, dwReadLen);
diff --git a/modules/rostests/winetests/imm32/imm32.c 
b/modules/rostests/winetests/imm32/imm32.c
index fef5b0dbb0d..407dfe1f6f7 100644
--- a/modules/rostests/winetests/imm32/imm32.c
+++ b/modules/rostests/winetests/imm32/imm32.c
@@ -293,7 +293,11 @@ static void cleanup(void) {
 }
 
 static void test_ImmNotifyIME(void) {
+#ifdef __REACTOS__
+    static char string[] = "wine";
+#else
     static const char string[] = "wine";
+#endif
     char resstr[16] = "";
     HIMC imc;
     BOOL ret;
@@ -422,7 +426,11 @@ static LRESULT WINAPI test_ime_wnd_proc(HWND hWnd, UINT 
msg, WPARAM wParam, LPAR
 static void test_ImmGetCompositionString(void)
 {
     HIMC imc;
+#ifdef __REACTOS__
+    static WCHAR string[] = {'w','i','n','e',0x65e5,0x672c,0x8a9e};
+#else
     static const WCHAR string[] = {'w','i','n','e',0x65e5,0x672c,0x8a9e};
+#endif
     char cstring[20];
     WCHAR wstring[20];
     LONG len;
diff --git a/sdk/include/psdk/imm.h b/sdk/include/psdk/imm.h
index fb7032181a7..ebd3bb4cb47 100644
--- a/sdk/include/psdk/imm.h
+++ b/sdk/include/psdk/imm.h
@@ -891,9 +891,9 @@ WINAPI
 ImmSetCompositionStringA(
   _In_ HIMC,
   _In_ DWORD dwIndex,
-  _In_reads_bytes_opt_(dwCompLen) LPCVOID lpComp,
+  _Inout_updates_bytes_opt_(dwCompLen) LPVOID lpComp,
   _In_ DWORD dwCompLen,
-  _In_reads_bytes_opt_(dwReadLen) LPCVOID lpRead,
+  _Inout_updates_bytes_opt_(dwReadLen) LPVOID lpRead,
   _In_ DWORD dwReadLen);
 
 BOOL
@@ -901,9 +901,9 @@ WINAPI
 ImmSetCompositionStringW(
   _In_ HIMC,
   _In_ DWORD dwIndex,
-  _In_reads_bytes_opt_(dwCompLen) LPCVOID lpComp,
+  _Inout_updates_bytes_opt_(dwCompLen) LPVOID lpComp,
   _In_ DWORD dwCompLen,
-  _In_reads_bytes_opt_(dwReadLen) LPCVOID lpRead,
+  _Inout_updates_bytes_opt_(dwReadLen) LPVOID lpRead,
   _In_ DWORD dwReadLen);
 
 #define ImmSetCompositionString WINELIB_NAME_AW(ImmSetCompositionString)

Reply via email to