1 /* 2 * PROJECT: ReactOS IMM32 3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) 4 * PURPOSE: Implementing IMM32 5 * COPYRIGHT: Copyright 1998 Patrik Stridvall 6 * Copyright 2002, 2003, 2007 CodeWeavers, Aric Stewart 7 * Copyright 2017 James Tabor <james.tabor@reactos.org> 8 * Copyright 2018 Amine Khaldi <amine.khaldi@reactos.org> 9 * Copyright 2020 Oleg Dubinskiy <oleg.dubinskij2013@yandex.ua> 10 * Copyright 2020-2021 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 11 */ 12 13 #pragma once 14 15 #include <stdio.h> 16 #include <stdlib.h> 17 18 /* PSDK/NDK Headers */ 19 #define WIN32_NO_STATUS 20 #include <windef.h> 21 #include <winbase.h> 22 #include <wingdi.h> 23 #include <winuser.h> 24 #include <winnls.h> 25 #include <winreg.h> 26 #include <winnls32.h> 27 #include <winver.h> 28 29 #include <imm.h> 30 #include <ddk/imm.h> 31 32 #define NTOS_MODE_USER 33 #include <ndk/umtypes.h> 34 #include <ndk/pstypes.h> 35 #include <ndk/rtlfuncs.h> 36 37 /* Public Win32K Headers */ 38 #include "ntuser.h" 39 #include "ntwin32.h" 40 41 /* Undocumented user definitions */ 42 #include <undocuser.h> 43 #include <imm32_undoc.h> 44 45 #include <strsafe.h> 46 47 #include <wine/debug.h> 48 #include <wine/list.h> 49 50 #define IMM_INIT_MAGIC 0x19650412 51 #define IMM_INVALID_CANDFORM ULONG_MAX 52 #define INVALID_HOTKEY_ID 0xFFFFFFFF 53 #define MAX_CANDIDATEFORM 4 54 #define MAX_IMM_FILENAME 80 55 56 #define LANGID_CHINESE_SIMPLIFIED MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED) 57 #define LANGID_CHINESE_TRADITIONAL MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL) 58 #define LANGID_JAPANESE MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT) 59 60 #define REGKEY_KEYBOARD_LAYOUTS L"System\\CurrentControlSet\\Control\\Keyboard Layouts" 61 #define REGKEY_IMM L"Software\\Microsoft\\Windows NT\\CurrentVersion\\IMM" 62 63 #define ROUNDUP4(n) (((n) + 3) & ~3) /* DWORD alignment */ 64 65 typedef struct REG_IME 66 { 67 HKL hKL; 68 WCHAR szImeKey[20]; /* "E0XXYYYY": "E0XX" is the device handle. "YYYY" is a LANGID. */ 69 WCHAR szFileName[80]; /* The IME module filename */ 70 } REG_IME, *PREG_IME; 71 72 extern HMODULE g_hImm32Inst; 73 extern RTL_CRITICAL_SECTION g_csImeDpi; 74 extern PIMEDPI g_pImeDpiList; 75 extern PSERVERINFO g_psi; 76 extern SHAREDINFO g_SharedInfo; 77 extern BYTE g_bClientRegd; 78 extern HANDLE g_hImm32Heap; 79 80 BOOL Imm32GetSystemLibraryPath(LPWSTR pszPath, DWORD cchPath, LPCWSTR pszFileName); 81 VOID APIENTRY LogFontAnsiToWide(const LOGFONTA *plfA, LPLOGFONTW plfW); 82 VOID APIENTRY LogFontWideToAnsi(const LOGFONTW *plfW, LPLOGFONTA plfA); 83 PWND FASTCALL ValidateHwndNoErr(HWND hwnd); 84 LPVOID FASTCALL ValidateHandleNoErr(HANDLE hObject, UINT uType); 85 BOOL APIENTRY Imm32CheckImcProcess(PIMC pIMC); 86 87 LPVOID APIENTRY Imm32HeapAlloc(DWORD dwFlags, DWORD dwBytes); 88 #define Imm32HeapFree(lpData) HeapFree(g_hImm32Heap, 0, (lpData)) 89 90 LPWSTR APIENTRY Imm32WideFromAnsi(LPCSTR pszA); 91 LPSTR APIENTRY Imm32AnsiFromWide(LPCWSTR pszW); 92 LONG APIENTRY IchWideFromAnsi(LONG cchAnsi, LPCSTR pchAnsi, UINT uCodePage); 93 LONG APIENTRY IchAnsiFromWide(LONG cchWide, LPCWSTR pchWide, UINT uCodePage); 94 PIMEDPI APIENTRY ImmLockOrLoadImeDpi(HKL hKL); 95 LPINPUTCONTEXT APIENTRY Imm32LockIMCEx(HIMC hIMC, BOOL fSelect); 96 BOOL APIENTRY Imm32ReleaseIME(HKL hKL); 97 98 static inline BOOL Imm32IsCrossThreadAccess(HIMC hIMC) 99 { 100 DWORD dwImeThreadId = (DWORD)NtUserQueryInputContext(hIMC, QIC_INPUTTHREADID); 101 DWORD dwThreadId = GetCurrentThreadId(); 102 return (dwImeThreadId != dwThreadId); 103 } 104 105 static inline BOOL Imm32IsCrossProcessAccess(HWND hWnd) 106 { 107 return (NtUserQueryWindow(hWnd, QUERY_WINDOW_UNIQUE_PROCESS_ID) != 108 (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess); 109 } 110 111 BOOL WINAPI Imm32IsImcAnsi(HIMC hIMC); 112 113 #define ImeDpi_IsUnicode(pImeDpi) ((pImeDpi)->ImeInfo.fdwProperty & IME_PROP_UNICODE) 114 #define Imm32IsImmMode() (g_psi && (g_psi->dwSRVIFlags & SRVINFO_IMM32)) 115 #define Imm32IsCiceroMode() (g_psi && (g_psi->dwSRVIFlags & SRVINFO_CICERO_ENABLED)) 116 #define Imm32Is16BitMode() (GetWin32ClientInfo()->dwTIFlags & TIF_16BIT) 117 118 DWORD APIENTRY 119 CandidateListWideToAnsi(const CANDIDATELIST *pWideCL, LPCANDIDATELIST pAnsiCL, DWORD dwBufLen, 120 UINT uCodePage); 121 DWORD APIENTRY 122 CandidateListAnsiToWide(const CANDIDATELIST *pAnsiCL, LPCANDIDATELIST pWideCL, DWORD dwBufLen, 123 UINT uCodePage); 124 125 BOOL APIENTRY 126 Imm32NotifyAction(HIMC hIMC, HWND hwnd, DWORD dwAction, DWORD_PTR dwIndex, DWORD_PTR dwValue, 127 DWORD_PTR dwCommand, DWORD_PTR dwData); 128 129 DWORD APIENTRY Imm32AllocAndBuildHimcList(DWORD dwThreadId, HIMC **pphList); 130 131 INT APIENTRY 132 Imm32ImeMenuAnsiToWide(const IMEMENUITEMINFOA *pItemA, LPIMEMENUITEMINFOW pItemW, 133 UINT uCodePage, BOOL bBitmap); 134 INT APIENTRY 135 Imm32ImeMenuWideToAnsi(const IMEMENUITEMINFOW *pItemW, LPIMEMENUITEMINFOA pItemA, 136 UINT uCodePage); 137 138 PIME_STATE APIENTRY Imm32FetchImeState(LPINPUTCONTEXTDX pIC, HKL hKL); 139 PIME_SUBSTATE APIENTRY Imm32FetchImeSubState(PIME_STATE pState, HKL hKL); 140 141 BOOL APIENTRY 142 Imm32LoadImeStateSentence(LPINPUTCONTEXTDX pIC, PIME_STATE pState, HKL hKL); 143 BOOL APIENTRY 144 Imm32SaveImeStateSentence(LPINPUTCONTEXTDX pIC, PIME_STATE pState, HKL hKL); 145 146 DWORD APIENTRY 147 Imm32ReconvertAnsiFromWide(LPRECONVERTSTRING pDest, const RECONVERTSTRING *pSrc, UINT uCodePage); 148 DWORD APIENTRY 149 Imm32ReconvertWideFromAnsi(LPRECONVERTSTRING pDest, const RECONVERTSTRING *pSrc, UINT uCodePage); 150 151 HRESULT APIENTRY Imm32StrToUInt(LPCWSTR pszText, LPDWORD pdwValue, ULONG nBase); 152 HRESULT APIENTRY Imm32UIntToStr(DWORD dwValue, ULONG nBase, LPWSTR pszBuff, USHORT cchBuff); 153 BOOL APIENTRY Imm32LoadImeVerInfo(PIMEINFOEX pImeInfoEx); 154 UINT APIENTRY Imm32GetRegImes(PREG_IME pLayouts, UINT cLayouts); 155 BOOL APIENTRY Imm32WriteRegIme(HKL hKL, LPCWSTR pchFilePart, LPCWSTR pszLayout); 156 HKL APIENTRY Imm32GetNextHKL(UINT cKLs, const REG_IME *pLayouts, WORD wLangID); 157 BOOL APIENTRY Imm32CopyFile(LPWSTR pszOldFile, LPCWSTR pszNewFile); 158