https://git.reactos.org/?p=reactos.git;a=commitdiff;h=aa8fc872a098d261e13e4…
commit aa8fc872a098d261e13e48aeb32fb85808e36d1d
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sun Oct 17 19:32:48 2021 +0900
Commit: GitHub <noreply(a)github.com>
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)