https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a8a47036995ccaff4f02a…
commit a8a47036995ccaff4f02a922ab2d1fa8f849339d
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Tue Dec 26 10:31:53 2023 +0900
Commit: GitHub <noreply(a)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.mz(a)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);
+}