https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a8a47036995ccaff4f02a922ab2d1fa8f849339d
commit a8a47036995ccaff4f02a922ab2d1fa8f849339d Author: Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> AuthorDate: Tue Dec 26 10:31:53 2023 +0900 Commit: GitHub <nore...@github.com> CommitDate: Tue Dec 26 10:31:53 2023 +0900 [MSCTF][SDK] Implement TF_RegisterLangBarAddIn etc. (#6229) - Add dll/win32/msctf/utils.cpp. - Implement TF_RegisterLangBarAddIn and TF_UnregisterLangBarAddIn. - Strengthen <cicero/cicreg.h>. - Modify msctf.spec. CORE-19361 --- dll/win32/msctf/CMakeLists.txt | 7 ++- dll/win32/msctf/msctf.spec | 2 + dll/win32/msctf/utils.cpp | 102 +++++++++++++++++++++++++++++++++++ sdk/include/reactos/cicero/cicbase.h | 2 +- sdk/include/reactos/cicero/cicreg.h | 37 ++++++++++++- 5 files changed, 146 insertions(+), 4 deletions(-) diff --git a/dll/win32/msctf/CMakeLists.txt b/dll/win32/msctf/CMakeLists.txt index 863559f5270..d8caf9a8e04 100644 --- a/dll/win32/msctf/CMakeLists.txt +++ b/dll/win32/msctf/CMakeLists.txt @@ -20,13 +20,18 @@ list(APPEND SOURCE precomp.h ${CMAKE_CURRENT_BINARY_DIR}/msctf_stubs.c) +list(APPEND PCH_SKIP_SOURCE + utils.cpp) + add_library(msctf MODULE ${SOURCE} + ${PCH_SKIP_SOURCE} version.rc ${CMAKE_CURRENT_BINARY_DIR}/msctf.def) set_module_type(msctf win32dll) target_link_libraries(msctf uuid wine) -add_importlibs(msctf ole32 oleaut32 user32 advapi32 advapi32_vista msvcrt kernel32 ntdll) +add_importlibs(msctf user32 advapi32 advapi32_vista msvcrt kernel32 ntdll) +add_delay_importlibs(msctf ole32 oleaut32) add_pch(msctf precomp.h SOURCE) add_cd_file(TARGET msctf DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/msctf/msctf.spec b/dll/win32/msctf/msctf.spec index e5a1a714c00..186e1cadac2 100644 --- a/dll/win32/msctf/msctf.spec +++ b/dll/win32/msctf/msctf.spec @@ -34,3 +34,5 @@ @ stub TF_MlngInfoCount @ stub TF_RunInputCPL @ stdcall -stub TF_PostAllThreadMsg(long long) +@ stdcall TF_RegisterLangBarAddIn(ptr wstr long) +@ stdcall TF_UnregisterLangBarAddIn(ptr long) diff --git a/dll/win32/msctf/utils.cpp b/dll/win32/msctf/utils.cpp new file mode 100644 index 00000000000..9d0d455f8ad --- /dev/null +++ b/dll/win32/msctf/utils.cpp @@ -0,0 +1,102 @@ +/* + * PROJECT: ReactOS msctf.dll + * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later) + * PURPOSE: Text Framework Services + * COPYRIGHT: Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> + */ + +#include <stdlib.h> + +#define WIN32_LEAN_AND_MEAN +#define WIN32_NO_STATUS +#define COBJMACROS +#define INITGUID +#define _EXTYPES_H + +#include <windows.h> +#include <imm.h> +#include <ddk/immdev.h> +#include <cguid.h> +#include <msctf.h> +#include <ctffunc.h> +#include <shlwapi.h> +#include <strsafe.h> + +#include <cicero/cicreg.h> + +#include <wine/debug.h> + +WINE_DEFAULT_DEBUG_CHANNEL(msctf); + +/*********************************************************************** + * TF_RegisterLangBarAddIn (MSCTF.@) + * + * @implemented + */ +EXTERN_C HRESULT WINAPI +TF_RegisterLangBarAddIn( + _In_ REFGUID rguid, + _In_ LPCWSTR pszFilePath, + _In_ DWORD dwFlags) +{ + TRACE("(%s, %s, 0x%lX)\n", debugstr_guid(&rguid), debugstr_w(pszFilePath), dwFlags); + + if (!pszFilePath || IsEqualGUID(rguid, GUID_NULL)) + { + ERR("E_INVALIDARG\n"); + return E_INVALIDARG; + } + + WCHAR szBuff[MAX_PATH], szGUID[40]; + StringCchCopyW(szBuff, _countof(szBuff), L"SOFTWARE\\Microsoft\\CTF\\LangBarAddIn\\"); + StringFromGUID2(rguid, szGUID, _countof(szGUID)); + StringCchCatW(szBuff, _countof(szBuff), szGUID); + + CicRegKey regKey; + HKEY hBaseKey = ((dwFlags & 1) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER); + LSTATUS error = regKey.Create(hBaseKey, szBuff); + if (error == ERROR_SUCCESS) + { + error = regKey.SetSz(L"FilePath", pszFilePath); + if (error == ERROR_SUCCESS) + error = regKey.SetDword(L"Enable", !!(dwFlags & 4)); + } + + return ((error == ERROR_SUCCESS) ? S_OK : E_FAIL); +} + +/*********************************************************************** + * TF_UnregisterLangBarAddIn (MSCTF.@) + * + * @implemented + */ +EXTERN_C HRESULT WINAPI +TF_UnregisterLangBarAddIn( + _In_ REFGUID rguid, + _In_ DWORD dwFlags) +{ + TRACE("(%s, 0x%lX)\n", debugstr_guid(&rguid), dwFlags); + + if (IsEqualGUID(rguid, GUID_NULL)) + { + ERR("E_INVALIDARG\n"); + return E_INVALIDARG; + } + + WCHAR szSubKey[MAX_PATH]; + StringCchCopyW(szSubKey, _countof(szSubKey), L"SOFTWARE\\Microsoft\\CTF\\LangBarAddIn\\"); + + CicRegKey regKey; + HKEY hBaseKey = ((dwFlags & 1) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER); + LSTATUS error = regKey.Open(hBaseKey, szSubKey, KEY_ALL_ACCESS); + HRESULT hr = E_FAIL; + if (error == ERROR_SUCCESS) + { + WCHAR szGUID[40]; + StringFromGUID2(rguid, szGUID, _countof(szGUID)); + regKey.RecurseDeleteKey(szGUID); + hr = S_OK; + } + + return hr; +} diff --git a/sdk/include/reactos/cicero/cicbase.h b/sdk/include/reactos/cicero/cicbase.h index 6bf6a491e80..28f5f96543f 100644 --- a/sdk/include/reactos/cicero/cicbase.h +++ b/sdk/include/reactos/cicero/cicbase.h @@ -191,7 +191,7 @@ CicSystemModulePath::Init( if (bSysWinDir) { // Usually C:\Windows or C:\ReactOS - cchPath = ::GetSystemWindowsDirectory(m_szPath, _countof(m_szPath)); + cchPath = ::GetSystemWindowsDirectoryW(m_szPath, _countof(m_szPath)); } else { diff --git a/sdk/include/reactos/cicero/cicreg.h b/sdk/include/reactos/cicero/cicreg.h index 674d1d27ed2..da18e0bd49e 100644 --- a/sdk/include/reactos/cicero/cicreg.h +++ b/sdk/include/reactos/cicero/cicreg.h @@ -15,7 +15,7 @@ public: HKEY m_hKey; CicRegKey() : m_hKey(NULL) { } - ~CicRegKey() { Close(); } + virtual ~CicRegKey() { Close(); } operator HKEY() { return m_hKey; } @@ -43,7 +43,7 @@ public: LSTATUS SetDword(LPCWSTR pszValueName, DWORD dwValue) { - return ::RegSetValueExW(m_hKey, pszValueName, 0, REG_DWORD, &dwValue, sizeof(dwValue)); + return ::RegSetValueExW(m_hKey, pszValueName, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue)); } LSTATUS QuerySz(LPCWSTR pszValueName, LPWSTR pszValue, DWORD cchValueMax); @@ -53,6 +53,13 @@ public: DWORD cbValue = (lstrlenW(pszValue) + 1) * sizeof(WCHAR); return ::RegSetValueExW(m_hKey, pszValueName, 0, REG_SZ, (LPBYTE)pszValue, cbValue); } + + LSTATUS DeleteSubKey(LPCWSTR lpSubKey) + { + return ::RegDeleteKeyW(m_hKey, lpSubKey); + } + + LSTATUS RecurseDeleteKey(LPCWSTR lpSubKey); }; /******************************************************************************/ @@ -124,3 +131,29 @@ CicRegKey::QuerySz(LPCWSTR pszValueName, LPWSTR pszValue, DWORD cchValueMax) return error; } + +inline LSTATUS +CicRegKey::RecurseDeleteKey(LPCWSTR lpSubKey) +{ + CicRegKey regKey; + LSTATUS error = regKey.Open(m_hKey, lpSubKey, KEY_READ | KEY_WRITE); + if (error != ERROR_SUCCESS) + return error; + + WCHAR szName[MAX_PATH]; + DWORD cchName; + do + { + cchName = _countof(szName); + error = ::RegEnumKeyExW(regKey, 0, szName, &cchName, NULL, NULL, NULL, NULL); + if (error != ERROR_SUCCESS) + break; + + szName[_countof(szName) - 1] = UNICODE_NULL; + error = regKey.RecurseDeleteKey(szName); + } while (error == ERROR_SUCCESS); + + regKey.Close(); + + return DeleteSubKey(lpSubKey); +}