diff --git a/sdk/include/reactos/imm32_undoc.h b/sdk/include/reactos/imm32_undoc.h index 5897579654a..8b1d1a12b78 100644 --- a/sdk/include/reactos/imm32_undoc.h +++ b/sdk/include/reactos/imm32_undoc.h @@ -31,6 +31,18 @@ extern "C" { #define WM_IME_SYSTEM 0x00000287 +/* The additional dwIndex value for ImmGetCompositionStringA/W */ +#define GCS_PRIVATE 0x8000 + +/* Used in ImmGetCompositionStringA/W */ +typedef struct tagCOMPSTR_PRIVATE +{ + DWORD dwUnknown0; /* FIXME: Rename */ + DWORD dwUnknown1; /* FIXME: Rename */ + DWORD dwLen; + DWORD dwOffset; +} COMPSTR_PRIVATE, *PCOMPSTR_PRIVATE, *LPCOMPSTR_PRIVATE; + /* wParam for WM_IME_SYSTEM */ #define IMS_NOTIFYIMESHOW 0x05 #define IMS_UPDATEIMEUI 0x06 @@ -330,6 +342,7 @@ HRESULT WINAPI CtfImmLastEnabledWndDestroy(_In_ BOOL bCreate); HRESULT WINAPI CtfImmTIMActivate(_In_ HKL hKL); BOOL WINAPI CtfImmIsTextFrameServiceDisabled(VOID); BOOL WINAPI CtfImmIsCiceroEnabled(VOID); +BOOL WINAPI CtfImmIsGuidMapEnable(_In_ HIMC hIMC); LRESULT WINAPI CtfImmDispatchDefImeMessage( diff --git a/win32ss/user/imm32/compstr.c b/win32ss/user/imm32/compstr.c index 8358f42dc43..f2be03aa0fd 100644 --- a/win32ss/user/imm32/compstr.c +++ b/win32ss/user/imm32/compstr.c @@ -6,7 +6,7 @@ * Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart * Copyright 2017 James Tabor * Copyright 2018 Amine Khaldi - * Copyright 2020-2021 Katayama Hirofumi MZ + * Copyright 2020-2026 Katayama Hirofumi MZ */ #include "precomp.h" @@ -214,6 +214,35 @@ Imm32CompClauseWideToAnsi(const DWORD *source, INT slen, LPCWSTR text, #define CS_DoAttr CS_DoStrA #define CS_DoClause CS_DoStrA +static DWORD CS_DoPrivate(HIMC hIMC, const COMPOSITIONSTRING *pCS, PVOID pBuffer, DWORD dwBufLen) +{ + if (!CtfImmIsGuidMapEnable(hIMC) || pCS->dwPrivateSize < sizeof(COMPSTR_PRIVATE)) + return IMM_ERROR_GENERAL; + + /* Check boundary #1 (ReactOS only) */ + DWORD dwPrivateOffset = pCS->dwPrivateOffset; + if (dwPrivateOffset >= pCS->dwSize || dwPrivateOffset + pCS->dwPrivateSize > pCS->dwSize) + return IMM_ERROR_GENERAL; + + const BYTE *pbCS = (const BYTE *)pCS; + const COMPSTR_PRIVATE *pPrivate = (const COMPSTR_PRIVATE *)(pbCS + dwPrivateOffset); + DWORD dwLen = pPrivate->dwLen, dwOffset = pPrivate->dwOffset; + + /* Check boundary #2 (ReactOS only) */ + if (dwPrivateOffset + dwOffset > pCS->dwPrivateSize || + dwPrivateOffset + dwOffset + dwLen > pCS->dwPrivateSize) + { + return IMM_ERROR_GENERAL; + } + + if (!dwBufLen) + return dwLen; + + DWORD ret = min(dwBufLen, dwLen); + CopyMemory(pBuffer, (const BYTE *)pPrivate + dwOffset, ret); + return ret; +} + static LONG Imm32GetCompStrA(HIMC hIMC, const COMPOSITIONSTRING *pCS, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen, BOOL bAnsiClient, UINT uCodePage) @@ -270,6 +299,9 @@ Imm32GetCompStrA(HIMC hIMC, const COMPOSITIONSTRING *pCS, DWORD dwIndex, CS_DoClause(pCS, ResultClause); break; + case GCS_PRIVATE: + return CS_DoPrivate(hIMC, pCS, lpBuf, dwBufLen); + default: FIXME("0x%X\n", dwIndex); return IMM_ERROR_GENERAL; @@ -355,6 +387,9 @@ Imm32GetCompStrA(HIMC hIMC, const COMPOSITIONSTRING *pCS, DWORD dwIndex, lpBuf, dwBufLen, uCodePage); break; + case GCS_PRIVATE: + return CS_DoPrivate(hIMC, pCS, lpBuf, dwBufLen); + default: FIXME("0x%X\n", dwIndex); return IMM_ERROR_GENERAL; @@ -447,6 +482,9 @@ Imm32GetCompStrW(HIMC hIMC, const COMPOSITIONSTRING *pCS, DWORD dwIndex, lpBuf, dwBufLen, uCodePage); break; + case GCS_PRIVATE: + return CS_DoPrivate(hIMC, pCS, lpBuf, dwBufLen); + default: FIXME("0x%X\n", dwIndex); return IMM_ERROR_GENERAL; @@ -504,6 +542,9 @@ Imm32GetCompStrW(HIMC hIMC, const COMPOSITIONSTRING *pCS, DWORD dwIndex, CS_DoClause(pCS, ResultClause); break; + case GCS_PRIVATE: + return CS_DoPrivate(hIMC, pCS, lpBuf, dwBufLen); + default: FIXME("0x%X\n", dwIndex); return IMM_ERROR_GENERAL;